mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-20 04:37:31 +07:00
Merge branch 'master' into crater
This commit is contained in:
@ -81,7 +81,7 @@ public class AndroidLauncher extends AndroidApplication{
|
||||
if(VERSION.SDK_INT >= VERSION_CODES.Q){
|
||||
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType(extension.equals("zip") ? "application/zip" : "*/*");
|
||||
intent.setType(extension.equals("zip") && !open ? "application/zip" : "*/*");
|
||||
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
||||
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
||||
Uri uri = in.getData();
|
||||
|
@ -1,297 +0,0 @@
|
||||
package mindustry.annotations.impl;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import com.squareup.javapoet.*;
|
||||
import com.squareup.javapoet.TypeSpec.*;
|
||||
import com.sun.source.tree.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.annotations.*;
|
||||
import mindustry.annotations.util.*;
|
||||
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.type.*;
|
||||
|
||||
@SupportedAnnotationTypes({
|
||||
"mindustry.annotations.Annotations.EntityDef",
|
||||
"mindustry.annotations.Annotations.EntityInterface",
|
||||
"mindustry.annotations.Annotations.BaseComponent"
|
||||
})
|
||||
public class EntityProcess extends BaseProcessor{
|
||||
Array<Definition> definitions = new Array<>();
|
||||
Array<Stype> baseComponents;
|
||||
ObjectMap<Stype, Array<Stype>> componentDependencies = new ObjectMap<>();
|
||||
ObjectMap<Stype, Array<Stype>> defComponents = new ObjectMap<>();
|
||||
ObjectSet<String> imports = new ObjectSet<>();
|
||||
|
||||
{
|
||||
rounds = 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(RoundEnvironment env) throws Exception{
|
||||
|
||||
//round 1: get component classes and generate interfaces for them
|
||||
if(round == 1){
|
||||
baseComponents = types(BaseComponent.class);
|
||||
Array<Stype> allDefs = types(EntityDef.class);
|
||||
|
||||
ObjectSet<Stype> allComponents = new ObjectSet<>();
|
||||
|
||||
//find all components used...
|
||||
for(Stype type : allDefs){
|
||||
allComponents.addAll(allComponents(type));
|
||||
}
|
||||
|
||||
//add all components w/ dependencies
|
||||
allComponents.addAll(types(Depends.class).map(s -> Array.withArrays(getDependencies(s), s)).flatten());
|
||||
|
||||
//add component imports
|
||||
for(Stype comp : allComponents){
|
||||
imports.addAll(getImports(comp.e));
|
||||
}
|
||||
|
||||
//create component interfaces
|
||||
for(Stype component : allComponents){
|
||||
TypeSpec.Builder inter = TypeSpec.interfaceBuilder(interfaceName(component)).addModifiers(Modifier.PUBLIC).addAnnotation(EntityInterface.class);
|
||||
|
||||
//implement extra interfaces these components may have, e.g. position
|
||||
for(Stype extraInterface : component.interfaces()){
|
||||
inter.addSuperinterface(extraInterface.mirror());
|
||||
}
|
||||
|
||||
//implement super interfaces
|
||||
Array<Stype> depends = getDependencies(component);
|
||||
for(Stype type : depends){
|
||||
inter.addSuperinterface(ClassName.get(packageName, interfaceName(type)));
|
||||
}
|
||||
|
||||
for(Svar field : component.fields().select(e -> !e.is(Modifier.STATIC) && !e.is(Modifier.PRIVATE) && !e.is(Modifier.TRANSIENT))){
|
||||
String cname = Strings.capitalize(field.name());
|
||||
//getter
|
||||
inter.addMethod(MethodSpec.methodBuilder("get" + cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC).returns(field.tname()).build());
|
||||
//setter
|
||||
if(!field.is(Modifier.FINAL)) inter.addMethod(MethodSpec.methodBuilder("set" + cname).addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC).addParameter(field.tname(), field.name()).build());
|
||||
}
|
||||
|
||||
//add utility methods to interface
|
||||
for(Smethod method : component.methods()){
|
||||
inter.addMethod(MethodSpec.methodBuilder(method.name())
|
||||
.addExceptions(method.thrownt())
|
||||
.addTypeVariables(method.typeVariables().map(TypeVariableName::get))
|
||||
.returns(method.ret().toString().equals("void") ? TypeName.VOID : method.retn())
|
||||
.addParameters(method.params().map(v -> ParameterSpec.builder(v.tname(), v.name())
|
||||
.build())).addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).build());
|
||||
}
|
||||
|
||||
write(inter);
|
||||
}
|
||||
|
||||
//look at each definition
|
||||
for(Stype type : allDefs){
|
||||
if(!type.name().endsWith("Def")){
|
||||
err("All entity def names must end with 'Def'", type.e);
|
||||
}
|
||||
String name = type.name().replace("Def", "Gen"); //TODO remove 'gen'
|
||||
TypeSpec.Builder builder = TypeSpec.classBuilder(name).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
|
||||
Array<Stype> components = allComponents(type);
|
||||
ObjectMap<String, Array<Smethod>> methods = new ObjectMap<>();
|
||||
|
||||
//add all components
|
||||
for(Stype comp : components){
|
||||
|
||||
//write fields to the class; ignoring transient ones
|
||||
Array<Svar> fields = comp.fields().select(f -> !f.is(Modifier.TRANSIENT));
|
||||
for(Svar f : fields){
|
||||
VariableTree tree = f.tree();
|
||||
FieldSpec.Builder fbuilder = FieldSpec.builder(f.tname(), f.name());
|
||||
//add initializer if it exists
|
||||
if(tree.getInitializer() != null){
|
||||
fbuilder.initializer(tree.getInitializer().toString());
|
||||
}
|
||||
builder.addField(fbuilder.build());
|
||||
}
|
||||
|
||||
//get all utility methods from components
|
||||
for(Smethod elem : comp.methods()){
|
||||
methods.getOr(elem.toString(), Array::new).add(elem);
|
||||
}
|
||||
}
|
||||
|
||||
//add all methods from components
|
||||
for(ObjectMap.Entry<String, Array<Smethod>> entry : methods){
|
||||
//representative method
|
||||
Smethod first = entry.value.first();
|
||||
//build method using same params/returns
|
||||
MethodSpec.Builder mbuilder = MethodSpec.methodBuilder(first.name()).addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
mbuilder.addTypeVariables(first.typeVariables().map(TypeVariableName::get));
|
||||
mbuilder.returns(first.retn());
|
||||
mbuilder.addExceptions(first.thrownt());
|
||||
|
||||
for(Svar var : first.params()){
|
||||
mbuilder.addParameter(var.tname(), var.name());
|
||||
}
|
||||
|
||||
//only write the block if it's a void method with several entries
|
||||
boolean writeBlock = first.ret().toString().equals("void") && entry.value.size > 1;
|
||||
|
||||
if(entry.value.first().is(Modifier.ABSTRACT) && entry.value.size == 1){
|
||||
err(entry.value.first().up().getSimpleName() + " declares an abstract method. This method must be implemented in another component", entry.value.first());
|
||||
}
|
||||
|
||||
for(Smethod elem : entry.value){
|
||||
if(elem.is(Modifier.ABSTRACT)) continue;
|
||||
|
||||
//get all statements in the method, copy them over
|
||||
MethodTree methodTree = elem.tree();
|
||||
BlockTree blockTree = methodTree.getBody();
|
||||
String str = blockTree.toString();
|
||||
//name for code blocks in the methods
|
||||
String blockName = elem.up().getSimpleName().toString().toLowerCase().replace("comp", "");
|
||||
|
||||
//skip empty blocks
|
||||
if(str.replace("{", "").replace("\n", "").replace("}", "").replace("\t", "").replace(" ", "").isEmpty()){
|
||||
continue;
|
||||
}
|
||||
|
||||
//wrap scope to prevent variable leakage
|
||||
if(writeBlock){
|
||||
//replace return; with block break
|
||||
str = str.replace("return;", "break " + blockName + ";");
|
||||
mbuilder.addCode(blockName + ": {\n");
|
||||
}
|
||||
|
||||
//trim block
|
||||
str = str.substring(2, str.length() - 1);
|
||||
|
||||
//make sure to remove braces here
|
||||
mbuilder.addCode(str);
|
||||
|
||||
//end scope
|
||||
if(writeBlock) mbuilder.addCode("}\n");
|
||||
}
|
||||
|
||||
builder.addMethod(mbuilder.build());
|
||||
}
|
||||
|
||||
definitions.add(new Definition(builder, type));
|
||||
|
||||
}
|
||||
}else{
|
||||
//round 2: generate actual classes and implement interfaces
|
||||
Array<Stype> interfaces = types(EntityInterface.class);
|
||||
|
||||
//implement each definition
|
||||
for(Definition def : definitions){
|
||||
Array<Stype> components = allComponents(def.base);
|
||||
|
||||
//get interface for each component
|
||||
for(Stype comp : components){
|
||||
//implement the interface
|
||||
Stype inter = interfaces.find(i -> i.name().equals(interfaceName(comp)));
|
||||
def.builder.addSuperinterface(inter.tname());
|
||||
|
||||
//generate getter/setter for each method
|
||||
for(Smethod method : inter.methods()){
|
||||
if(method.name().length() <= 3) continue;
|
||||
|
||||
String var = Strings.camelize(method.name().substring(3));
|
||||
//make sure it's a real variable
|
||||
if(!Array.with(def.builder.fieldSpecs).contains(f -> f.name.equals(var))) continue;
|
||||
|
||||
if(method.name().startsWith("get")){
|
||||
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("return " + var).build());
|
||||
}else if(method.name().startsWith("set")){
|
||||
def.builder.addMethod(MethodSpec.overriding(method.e).addStatement("this." + var + " = " + var).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write(def.builder, imports.asArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Array<String> getImports(Element elem){
|
||||
return Array.with(trees.getPath(elem).getCompilationUnit().getImports()).map(Object::toString);
|
||||
}
|
||||
|
||||
/** @return interface for a component type */
|
||||
String interfaceName(Stype comp){
|
||||
String suffix = "Comp";
|
||||
if(!comp.name().endsWith(suffix)){
|
||||
err("All components must have names that end with 'Comp'.", comp.e);
|
||||
}
|
||||
return comp.name().substring(0, comp.name().length() - suffix.length()) + "c";
|
||||
}
|
||||
|
||||
/** @return all components that a entity def has */
|
||||
Array<Stype> allComponents(Stype type){
|
||||
if(!defComponents.containsKey(type)){
|
||||
//get base defs
|
||||
Array<Stype> components = Array.with(mirrors(type)).map(Stype::of);
|
||||
ObjectSet<Stype> out = new ObjectSet<>();
|
||||
for(Stype comp : components){
|
||||
//get dependencies for each def, add them
|
||||
out.add(comp);
|
||||
out.addAll(getDependencies(comp));
|
||||
}
|
||||
|
||||
defComponents.put(type, out.asArray());
|
||||
}
|
||||
|
||||
return defComponents.get(type);
|
||||
}
|
||||
|
||||
Array<Stype> getDependencies(Stype component){
|
||||
if(!componentDependencies.containsKey(component)){
|
||||
ObjectSet<Stype> out = new ObjectSet<>();
|
||||
out.addAll(component.superclasses());
|
||||
|
||||
//get dependency classes
|
||||
if(component.annotation(Depends.class) != null){
|
||||
try{
|
||||
component.annotation(Depends.class).value();
|
||||
}catch(MirroredTypesException e){
|
||||
out.addAll(Array.with(e.getTypeMirrors()).map(Stype::of));
|
||||
}
|
||||
}
|
||||
|
||||
//out now contains the base dependencies; finish constructing the tree
|
||||
ObjectSet<Stype> result = new ObjectSet<>();
|
||||
for(Stype type : out){
|
||||
result.add(type);
|
||||
result.addAll(getDependencies(type));
|
||||
}
|
||||
|
||||
if(component.annotation(BaseComponent.class) == null){
|
||||
result.addAll(baseComponents);
|
||||
}
|
||||
|
||||
componentDependencies.put(component, result.asArray());
|
||||
}
|
||||
|
||||
return componentDependencies.get(component);
|
||||
}
|
||||
|
||||
TypeMirror[] mirrors(Stype type){
|
||||
try{
|
||||
type.annotation(EntityDef.class).value();
|
||||
}catch(MirroredTypesException e){
|
||||
return e.getTypeMirrors().toArray(new TypeMirror[0]);
|
||||
}
|
||||
throw new IllegalArgumentException("Missing components: " + type);
|
||||
}
|
||||
|
||||
class Definition{
|
||||
final TypeSpec.Builder builder;
|
||||
final Stype base;
|
||||
|
||||
public Definition(Builder builder, Stype base){
|
||||
this.builder = builder;
|
||||
this.base = base;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ credits = Tekijät
|
||||
contributors = Kääntäjät ja avustajat
|
||||
discord = Liity Mindustryn Discordiin!
|
||||
link.discord.description = Mindustryn virallinen Discord-keskusteluhuone
|
||||
link.reddit.description = Mindustry subreddit
|
||||
link.reddit.description = Mindustryn alireddit
|
||||
link.github.description = Pelin lähdekoodi
|
||||
link.changelog.description = Lista päivityksien muutoksista
|
||||
link.dev-builds.description = Epävakaat kehitysversiot
|
||||
@ -21,15 +21,15 @@ gameover.pvp = [accent] {0}[] joukkue voittaa!
|
||||
highscore = [accent]Uusi ennätys!
|
||||
copied = Kopioitu.
|
||||
|
||||
load.sound = Ääni
|
||||
load.map = Kartat
|
||||
load.image = Kuvat
|
||||
load.content = Sisältö
|
||||
load.system = Systeemi
|
||||
load.mod = Modit
|
||||
load.scripts = Skriptit
|
||||
load.sound = Ääniä
|
||||
load.map = Karttoja
|
||||
load.image = Kuvia
|
||||
load.content = Sisältöä
|
||||
load.system = Järjestelmää
|
||||
load.mod = Modeja
|
||||
load.scripts = Skriptejä
|
||||
|
||||
be.update = A new Bleeding Edge build is available:
|
||||
be.update = Uusi kehitysversio on saatavilla:
|
||||
be.update.confirm = Lataa se ja käynnistä peli uudelleen?
|
||||
be.updating = Päivitetään...
|
||||
be.ignore = Sivuuta
|
||||
@ -37,20 +37,20 @@ be.noupdates = Ei päivityksiä saatavilla.
|
||||
be.check = Tarkista päivityksiä
|
||||
|
||||
schematic = Kaavio
|
||||
schematic.add = Tallenna Kaavio...
|
||||
schematic.add = Tallenna kaavio...
|
||||
schematics = Kaaviot
|
||||
schematic.replace = Kaavio tällä nimellä on jo olemassa. Haluatko korvata sen?
|
||||
schematic.import = Tuo Kaavio...
|
||||
schematic.exportfile = Luo Tiedosto
|
||||
schematic.importfile = Tuo Tiedosto
|
||||
schematic.browseworkshop = Selaa Työpajaa
|
||||
schematic.copy = Kopioi Leikepöydälle
|
||||
schematic.copy.import = Tou Leikepöydälle
|
||||
schematic.shareworkshop = Jaa työpajaan
|
||||
schematic.import = Tuo kaavio...
|
||||
schematic.exportfile = Vie tiedosto
|
||||
schematic.importfile = Tuo tiedosto
|
||||
schematic.browseworkshop = Selaa Workshoppia
|
||||
schematic.copy = Kopioi leikepöydälle
|
||||
schematic.copy.import = Tuo leikepöydältä
|
||||
schematic.shareworkshop = Jaa Workshoppiin
|
||||
schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Käännä Kaavio
|
||||
schematic.saved = Kaavio tallennettu.
|
||||
schematic.delete.confirm = Tämä kaavio poistetaan.
|
||||
schematic.rename = Uudelleennimeä Kaavio
|
||||
schematic.rename = Nimeä kaavio uudelleen
|
||||
schematic.info = {0}x{1}, {2} palikkaa
|
||||
|
||||
stat.wave = Tasoja voitettu:[accent] {0}
|
||||
@ -62,7 +62,7 @@ stat.delivered = Resursseja laukaistu:
|
||||
stat.rank = Lopullinen arvosana: [accent]{0}
|
||||
|
||||
launcheditems = [accent]Laukaistut tavarat
|
||||
launchinfo = [unlaunched][[LAUNCH] your core to obtain the items indicated in blue.
|
||||
launchinfo = [unlaunched][[LAUKAISE] ytimesi saadaksesi sinisellä merkityt tavarat.
|
||||
map.delete = Oletko varma että haluat poistaa kartan "[accent]{0}[]"?
|
||||
level.highscore = Ennätys: [accent]{0}
|
||||
level.select = Tason valinta
|
||||
@ -82,12 +82,12 @@ position = Sijainti
|
||||
close = Sulje
|
||||
website = Verkkosivu
|
||||
quit = Poistu
|
||||
save.quit = Tallenna ja Poistu
|
||||
save.quit = Tallenna ja poistu
|
||||
maps = Kartat
|
||||
maps.browse = Selaa Karttoja
|
||||
maps.browse = Selaa karttoja
|
||||
continue = Jatka
|
||||
maps.none = [lightgray]Karttoja ei löytynyt!
|
||||
invalid = Invalidi
|
||||
invalid = Virheellinen
|
||||
pickcolor = Valitse väri
|
||||
preparingconfig = Preparing Config
|
||||
preparingcontent = Preparing Content
|
||||
@ -95,29 +95,29 @@ uploadingcontent = Uploading Content
|
||||
uploadingpreviewfile = Uploading Preview File
|
||||
committingchanges = Comitting Changes
|
||||
done = Valmis
|
||||
feature.unsupported = Sinun laitteesi ei tue tätä toimintoa.
|
||||
feature.unsupported = Laitteesi ei tue tätä toimintoa.
|
||||
|
||||
mods.alphainfo = Pidä mielessä että modit ovat alpha-tilassa, ja[scarlet] ne voivat olla virheellisiä[].\nRaportoi kaikki virheet Mindustry GitHub-sivuille tai Discordiin.
|
||||
mods.alpha = [accent](Alpha)
|
||||
mods = Modit
|
||||
mods.none = [LIGHT_GRAY]Modeja ei löytynyt!
|
||||
mods.guide = Modaamisen opas
|
||||
mods.guide = Modaamisopas
|
||||
mods.report = Raportoi ohjelmistovirhe
|
||||
mods.openfolder = Avaa Modikansio
|
||||
mods.openfolder = Avaa modikansio
|
||||
mod.enabled = [lightgray]Käytössä
|
||||
mod.disabled = [scarlet]Epäkäytössä
|
||||
mod.disable = Laita pois päältä
|
||||
mod.delete.error = Modia ei pystynyt poistamaan. Tiedosto voi olla käytössä.
|
||||
mod.requiresversion = [scarlet]Tarvitsee vähintää pelin version: [accent]{0}
|
||||
mod.disabled = [scarlet]Pois käytöstä
|
||||
mod.disable = Poista käytössä
|
||||
mod.delete.error = Modia ei pystytty poistamaan. Tiedosto voi olla käytössä.
|
||||
mod.requiresversion = [scarlet]Tarvitsee vähintään pelin version: [accent]{0}
|
||||
mod.missingdependencies = [scarlet]Tarvitsee nämä modit: {0}
|
||||
mod.erroredcontent = [scarlet]Sisältö Virheet
|
||||
mod.erroredcontent = [scarlet]Sisältövirheet
|
||||
mod.errors = Virheitä on tapahtunut pelin ladatessa.
|
||||
mod.noerrorplay = [scarlet]Sinulla on virheellisiä modeja.[] Joko poista ne käytöstä tai korjaa virheet.
|
||||
mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled.
|
||||
mod.enable = Käytä
|
||||
mod.requiresrestart = Peli suljetaan jotta muutokset voisivat toteutua.
|
||||
mod.reloadrequired = [scarlet]Vaatii Uudelleenkäynnistystä
|
||||
mod.import = Tuo Modi
|
||||
mod.import = Tuo modi
|
||||
mod.import.github = Import GitHub Mod
|
||||
mod.item.remove = This item is part of the[accent] '{0}'[] mod. To remove it, uninstall that mod.
|
||||
mod.remove.confirm = Tämä modi poistetaan.
|
||||
@ -170,7 +170,7 @@ hosts.discovering.any = Etsitään Pelejä
|
||||
server.refreshing = Päivitetään palvelimen tietoja
|
||||
hosts.none = [lightgray]Paikallisia pelejä ei löytynyt!
|
||||
host.invalid = [scarlet]Isäntään ei voitu yhdistää.
|
||||
trace = Seuraa Pelaajaa
|
||||
trace = Seuraa pelaajaa
|
||||
trace.playername = Pelaajanimi: [accent]{0}
|
||||
trace.ip = IP-osoite: [accent]{0}
|
||||
trace.id = Uniikki tunniste: [accent]{0}
|
||||
@ -188,8 +188,8 @@ server.outdated = [crimson]Vanhentunut palvelin![]
|
||||
server.outdated.client = [crimson]Vanhentunut asiakasohjelma![]
|
||||
server.version = [gray]v{0} {1}
|
||||
server.custombuild = [yellow]Custom Build
|
||||
confirmban = Oletko varma että haluat potkia tämän pelaajan?
|
||||
confirmkick = Oletko varma että haluat poistaa tämän pelaajan?
|
||||
confirmban = Oletko varma että haluat antaa porttikiellon tälle pelaajalle?
|
||||
confirmkick = Oletko varma että haluat potkia tämän pelaajan?
|
||||
confirmvotekick = Oletko varma että haluat äänestää tämän pelaajan potkituksi?
|
||||
confirmunban = Oletko varma että haluat päästää tämän pelaajan takaisin?
|
||||
confirmadmin = Oletko varma että haluat antaa pelaajalle hallinto-oikeuksia?
|
||||
@ -208,32 +208,32 @@ server.port = Portti:
|
||||
server.addressinuse = Address already in use!
|
||||
server.invalidport = Invalid port number!
|
||||
server.error = [crimson]Error hosting server: [accent]{0}
|
||||
save.new = New Save
|
||||
save.new = Uusi tallennus
|
||||
save.overwrite = Are you sure you want to overwrite\nthis save slot?
|
||||
overwrite = Overwrite
|
||||
save.none = No saves found!
|
||||
saveload = Tallennetaan...
|
||||
savefail = Failed to save game!
|
||||
savefail = Pelin tallentaminen epäonnistui!
|
||||
save.delete.confirm = Are you sure you want to delete this save?
|
||||
save.delete = Delete
|
||||
save.export = Export Save
|
||||
save.import.invalid = [accent]This save is invalid!
|
||||
save.import.fail = [crimson]Failed to import save: [accent]{0}
|
||||
save.export.fail = [crimson]Failed to export save: [accent]{0}
|
||||
save.import = Tuo Tallennus
|
||||
save.import = Tuo tallennus
|
||||
save.newslot = Tallennuksen nimi:
|
||||
save.rename = Nimeä uudelleen
|
||||
save.rename.text = Uusi nimi:
|
||||
selectslot = Valitse tallennus.
|
||||
slot = [accent]Paikka {0}
|
||||
editmessage = Edit Message
|
||||
editmessage = Muokkaa viestiä
|
||||
save.corrupted = [accent]Tallennustiedosto korruptoitunut tai viallinen!\nJos olet päivittänyt juuri pelisi, tämä on todennäköisesti muutos tallennusmuodossa [scarlet]eikä[] virhe.
|
||||
empty = <tyhjä>
|
||||
on = Päällä
|
||||
off = Pois
|
||||
save.autosave = Automaattitallennus: {0}
|
||||
save.map = Kartta: {0}
|
||||
save.wave = Aalto {0}
|
||||
save.wave = Taso {0}
|
||||
save.mode = Gamemode: {0}
|
||||
save.date = Viimeksi tallennettu: {0}
|
||||
save.playtime = Peliaika: {0}
|
||||
@ -308,15 +308,15 @@ editor.waves = Tasot:
|
||||
editor.rules = Säännöt:
|
||||
editor.generation = Generaatio:
|
||||
editor.ingame = Muokka pelin sisällä
|
||||
editor.publish.workshop = Julkaise työpajaan
|
||||
editor.publish.workshop = Julkaise Workshoppiin
|
||||
editor.newmap = Uusi kartta
|
||||
workshop = Työpaja
|
||||
workshop = Workshop
|
||||
waves.title = Tasot
|
||||
waves.remove = Poista
|
||||
waves.never = <ei koskaan>
|
||||
waves.every = every
|
||||
waves.waves = wave(s)
|
||||
waves.perspawn = per spawni
|
||||
waves.perspawn = per syntymispiste
|
||||
waves.to = to
|
||||
waves.boss = Pomo
|
||||
waves.preview = Esikatselu
|
||||
@ -324,13 +324,13 @@ waves.edit = Muokkaa...
|
||||
waves.copy = Kopioi leikepöydälle
|
||||
waves.load = Lataa leikepöydältä
|
||||
waves.invalid = Invalid waves in clipboard.
|
||||
waves.copied = Aallot kopioitu.
|
||||
waves.copied = Tasot kopioitu.
|
||||
waves.none = No enemies defined.\nNote that empty wave layouts will automatically be replaced with the default layout.
|
||||
editor.default = [lightgray]<Default>
|
||||
details = Yksityiskohdat...
|
||||
edit = Muokkaa...
|
||||
editor.name = Nimi:
|
||||
editor.spawn = Spawni yksikkö
|
||||
editor.spawn = Luo yksikkö
|
||||
editor.removeunit = Poista yksikkö
|
||||
editor.teams = Joukkueet
|
||||
editor.errorload = Virhe ladattaessa tiedostoa:\n[accent]{0}
|
||||
@ -431,8 +431,8 @@ fps = FPS: {0}
|
||||
ping = Ping: {0}ms
|
||||
language.restart = Please restart your game for the language settings to take effect.
|
||||
settings = Asetukset
|
||||
tutorial = Tutoriaali
|
||||
tutorial.retake = Uusita Tutoriaali
|
||||
tutorial = Perehdytys
|
||||
tutorial.retake = Pelaa perehdytys uudelleen
|
||||
editor = Editori
|
||||
mapeditor = Kartan Editori
|
||||
|
||||
@ -449,8 +449,8 @@ launch = < LAUNCH >
|
||||
launch.title = Onnistunut laukaisu
|
||||
launch.next = [lightgray]next opportunity at wave {0}
|
||||
launch.unable2 = [scarlet]Unable to LAUNCH.[]
|
||||
launch.confirm = Tämä laukaisee kaikki resourssit ytimestäsi.\nEt voi enää palata takaisin.
|
||||
launch.skip.confirm = Jos ohitat nyt, voit laukaista vasta myöhemmissä tasoissa.
|
||||
launch.confirm = Tämä laukaisee kaikki resurssit ytimestäsi.\nEt voi enää palata takaisin.
|
||||
launch.skip.confirm = Jos ohitat nyt, voit laukaista vasta myöhemmillä tasoilla.
|
||||
uncover = Paljasta
|
||||
configure = Configure Loadout
|
||||
bannedblocks = Kielletyt Palikat
|
||||
@ -530,60 +530,60 @@ error.title = [crimson]An error has occured
|
||||
error.crashtitle = An error has occured
|
||||
blocks.input = Sisääntulo
|
||||
blocks.output = Ulostulo
|
||||
blocks.booster = Boostaa
|
||||
blocks.booster = Tehostaja
|
||||
block.unknown = [lightgray]???
|
||||
blocks.powercapacity = Energiakapasiteetti
|
||||
blocks.powershot = Energiaa/Ammus
|
||||
blocks.damage = Vahinko
|
||||
blocks.targetsair = Hyökkää Ilmaan
|
||||
blocks.targetsground = Hyökkää Maahan
|
||||
blocks.targetsair = Hyökkää ilmaan
|
||||
blocks.targetsground = Hyökkää maahan
|
||||
blocks.itemsmoved = Liikkumisnopeus
|
||||
blocks.launchtime = Aika Laukaisujen Välillä
|
||||
blocks.launchtime = Aika laukaisujen välillä
|
||||
blocks.shootrange = Kantama
|
||||
blocks.size = Koko
|
||||
blocks.liquidcapacity = Neste Kapasiteetti
|
||||
blocks.powerrange = Energia Kantama
|
||||
blocks.powerconnections = Maksimi konnektio määrä
|
||||
blocks.poweruse = Energian Käyttö
|
||||
blocks.liquidcapacity = Nestekapasiteetti
|
||||
blocks.powerrange = Energiakantama
|
||||
blocks.powerconnections = Maksimimäärä yhdistyksiä
|
||||
blocks.poweruse = Energian käyttö
|
||||
blocks.powerdamage = Energia/Vahinko
|
||||
blocks.itemcapacity = Tavara Kapasiteetti
|
||||
blocks.basepowergeneration = Kanta Enegian Generointi
|
||||
blocks.productiontime = Produktion Aika
|
||||
blocks.repairtime = Kokonaisen Palikan Korjaus Aika
|
||||
blocks.speedincrease = Nopeuden Kasvu
|
||||
blocks.itemcapacity = Tavarakapasiteetti
|
||||
blocks.basepowergeneration = Perus energiantuotto
|
||||
blocks.productiontime = Tuotantoaika
|
||||
blocks.repairtime = Kokonaisen palikan korjausaika
|
||||
blocks.speedincrease = Nopeuden kasvu
|
||||
blocks.range = Etäisyys
|
||||
blocks.drilltier = Porattavat
|
||||
blocks.drillspeed = Kanta Poran Nopeus
|
||||
blocks.boosteffect = Boostaamisen Vaikutus
|
||||
blocks.maxunits = Maksimi Määrä Yksikköjä
|
||||
blocks.boosteffect = Tehostamisem vaikutus
|
||||
blocks.maxunits = Maksimimäärä yksikköjä
|
||||
blocks.health = Elämäpisteet
|
||||
blocks.buildtime = Rakentamisen Aika
|
||||
blocks.buildcost = Rakentamisen Hinta
|
||||
blocks.buildtime = Rakentamisaika
|
||||
blocks.buildcost = Rakentamishinta
|
||||
blocks.inaccuracy = Epätarkkuus
|
||||
blocks.shots = Ammusta
|
||||
blocks.reload = Ammusta/Sekunnissa
|
||||
blocks.reload = Ammusta/sekunnissa
|
||||
blocks.ammo = Ammus
|
||||
|
||||
bar.drilltierreq = Parempi Pora Vaadittu
|
||||
bar.drillspeed = Poran Nopeus: {0}/s
|
||||
bar.pumpspeed = Pumpun Nopeus: {0}/s
|
||||
bar.drilltierreq = Parempi pora vaadittu
|
||||
bar.drillspeed = Poran nopeus: {0}/s
|
||||
bar.pumpspeed = Pumpun nopeus: {0}/s
|
||||
bar.efficiency = Tehokkuus: {0}%
|
||||
bar.powerbalance = Energia: {0}/s
|
||||
bar.powerstored = Säilöttynä: {0}/{1}
|
||||
bar.poweramount = Energia: {0}
|
||||
bar.poweroutput = Energian Ulostulo: {0}
|
||||
bar.poweroutput = Energiantuotto: {0}
|
||||
bar.items = Tavaroita: {0}
|
||||
bar.capacity = Kapasiteetti: {0}
|
||||
bar.liquid = Neste
|
||||
bar.heat = Lämpö
|
||||
bar.power = Energia
|
||||
bar.progress = Rakennuksen Edistys
|
||||
bar.progress = Rakennuksen edistys
|
||||
bar.spawned = Yksikköjä: {0}/{1}
|
||||
bar.input = Sisääntulo
|
||||
bar.output = Ulostulo
|
||||
|
||||
bullet.damage = [stat]{0}[lightgray] Vahinko
|
||||
bullet.splashdamage = [stat]{0}[lightgray] Alue vahinko ~[stat] {1}[lightgray] palikkaa
|
||||
bullet.splashdamage = [stat]{0}[lightgray] Aluevahinko ~[stat] {1}[lightgray] palikkaa
|
||||
bullet.incendiary = [stat]sytyttävä
|
||||
bullet.homing = [stat]itseohjautuva
|
||||
bullet.shock = [stat]shokki
|
||||
@ -591,15 +591,15 @@ bullet.frag = [stat]sirpaloituva
|
||||
bullet.knockback = [stat]{0}[lightgray] knockback
|
||||
bullet.freezing = [stat]jäädyttävä
|
||||
bullet.tarred = [stat]tervattu
|
||||
bullet.multiplier = [stat]{0}[lightgray]x ammusten multiplikaatio
|
||||
bullet.reload = [stat]{0}[lightgray]x ammunta nopeus
|
||||
bullet.multiplier = [stat]{0}[lightgray]x ammusten kerroin
|
||||
bullet.reload = [stat]{0}[lightgray]x ampumisnopeus
|
||||
|
||||
unit.blocks = palikat
|
||||
unit.powersecond = energia yksikköä/sekunti
|
||||
unit.liquidsecond = neste yksikköä/sekunti
|
||||
unit.powersecond = energiayksikköä/sekunti
|
||||
unit.liquidsecond = nesteyksikköä/sekunti
|
||||
unit.itemssecond = esinettä/sekunti
|
||||
unit.liquidunits = neste yksikköä
|
||||
unit.powerunits = energia yksikköä
|
||||
unit.liquidunits = nesteyksikköä
|
||||
unit.powerunits = energiayksikköä
|
||||
unit.degrees = astetta
|
||||
unit.seconds = sekunttia
|
||||
unit.persecond = /s
|
||||
@ -614,25 +614,25 @@ category.liquids = Neste
|
||||
category.items = Tavarat
|
||||
category.crafting = Ulos/Sisääntulo
|
||||
category.shooting = Ammunta
|
||||
category.optional = Mahdolliset Lumoukset
|
||||
category.optional = Mahdolliset parannukset
|
||||
setting.landscape.name = Lukitse tasavaakaan
|
||||
setting.shadows.name = Varjot
|
||||
setting.blockreplace.name = Automaattisia Palikka Suosituksia
|
||||
setting.linear.name = Lineararien Filteeraus
|
||||
setting.linear.name = Lineaarinen suodatus
|
||||
setting.hints.name = Vihjeet
|
||||
setting.buildautopause.name = Automaattisest Pysäytä Rakentaessa
|
||||
setting.animatedwater.name = Animoitu Vesi
|
||||
setting.animatedshields.name = Animoitu Kilpi
|
||||
setting.animatedwater.name = Animoitu vesi
|
||||
setting.animatedshields.name = Animoidut kilvet
|
||||
setting.antialias.name = Antialiaasi[lightgray] (vaatii uudelleenkäynnistyksen)[]
|
||||
setting.indicators.name = Vihollis/Puolulais Indikaattorit
|
||||
setting.autotarget.name = Automaatinen Tähtäys
|
||||
setting.keyboard.name = Hiiri+Näppäimistö Kontrollit
|
||||
setting.touchscreen.name = Kosketusnäyttö kontrollit
|
||||
setting.keyboard.name = Hiiri+Näppäimistö -ohjaus
|
||||
setting.touchscreen.name = Kosketusnäyttöohjaus
|
||||
setting.fpscap.name = Maksimi FPS
|
||||
setting.fpscap.none = Ei Mitään
|
||||
setting.fpscap.text = {0} FPS
|
||||
setting.uiscale.name = UI Koko[lightgray] (vaatii uudelleenkäynnistyksen)[]
|
||||
setting.swapdiagonal.name = Aina Vino Korvaus
|
||||
setting.swapdiagonal.name = Aina vino korvaus
|
||||
setting.difficulty.training = Treeni
|
||||
setting.difficulty.easy = Helppo
|
||||
setting.difficulty.normal = Keskivaikea
|
||||
@ -641,10 +641,10 @@ setting.difficulty.insane = Järjetön
|
||||
setting.difficulty.name = Vaikeustaso:
|
||||
setting.screenshake.name = Näytön keikkuminen
|
||||
setting.effects.name = Naytön Efektit
|
||||
setting.destroyedblocks.name = Näytä Tuhoutuneet Palikat
|
||||
setting.destroyedblocks.name = Näytä tuhoutuneet palikat
|
||||
setting.conveyorpathfinding.name = Conveyor Placement Pathfinding
|
||||
setting.coreselect.name = Allow Schematic Cores
|
||||
setting.sensitivity.name = Kontrollin Herkkyys
|
||||
setting.sensitivity.name = Ohjauksen herkkyys
|
||||
setting.saveinterval.name = Tallennuksen Aikaväli
|
||||
setting.seconds = {0} Sekunttia
|
||||
setting.blockselecttimeout.name = Block Select Timeout
|
||||
@ -652,35 +652,35 @@ setting.milliseconds = {0} millisekunttia
|
||||
setting.fullscreen.name = Fullscreen
|
||||
setting.borderlesswindow.name = Borderless Window[lightgray] (vaatii uudelleenkäynnistyksen)
|
||||
setting.fps.name = Näytä FPS
|
||||
setting.blockselectkeys.name = Bäytä Palikan Selektio Kontrollit
|
||||
setting.blockselectkeys.name = Näytä palikan valintaohjaimet
|
||||
setting.vsync.name = VSync
|
||||
setting.pixelate.name = Pixeloi[lightgray] (poistaa animaation käytöstä)
|
||||
setting.minimap.name = Näytä Minimappi
|
||||
setting.minimap.name = Näytä pienoiskartta
|
||||
setting.position.name = Näytä pelaajan sijainti
|
||||
setting.musicvol.name = Musiikin Äänenvoimakkuus
|
||||
setting.ambientvol.name = Tausta Äänet
|
||||
setting.mutemusic.name = Sulje Musiikki
|
||||
setting.sfxvol.name = SFX Volyymi
|
||||
setting.mutesound.name = Sulje Äänet
|
||||
setting.musicvol.name = Musiikin äänenvoimakkuus
|
||||
setting.ambientvol.name = Taustaäänet
|
||||
setting.mutemusic.name = Mykistä musiikki
|
||||
setting.sfxvol.name = SFX-voimakkuus
|
||||
setting.mutesound.name = Mykistä äänet
|
||||
setting.crashreport.name = Send Anonymous Crash Reports
|
||||
setting.savecreate.name = Luo Automaattisesti Tallennukset
|
||||
setting.savecreate.name = Luo tallenuksia automaattisesti
|
||||
setting.publichost.name = Public Game Visibility
|
||||
setting.chatopacity.name = Chatin Läpinäkymättömyys
|
||||
setting.lasersopacity.name = Energia Laaserin Läpinäkymattämyys
|
||||
setting.playerchat.name = Näytä Pelinsisäinen Keskustelu
|
||||
setting.chatopacity.name = Keskustelun läpinäkymättömyys
|
||||
setting.lasersopacity.name = Energia laserin läpinäkymättömyys
|
||||
setting.playerchat.name = Näytä pelinsisäinen keskustelu
|
||||
public.confirm = Do you want to make your game public?\n[accent]Anyone will be able to join your games.\n[lightgray]This can be changed later in Settings->Game->Public Game Visibility.
|
||||
public.beta = Note that beta versions of the game cannot make public lobbies.
|
||||
uiscale.reset = UI scale has been changed.\nPress "OK" to confirm this scale.\n[scarlet]Reverting and exiting in[accent] {0}[] seconds...
|
||||
uiscale.cancel = Peruuta ja Poistu
|
||||
uiscale.cancel = Peruuta ja poistu
|
||||
setting.bloom.name = Bloom
|
||||
keybind.title = Rebind Keys
|
||||
keybinds.mobile = [scarlet]Most keybinds here are not functional on mobile. Only basic movement is supported.
|
||||
category.general.name = General
|
||||
category.view.name = View
|
||||
category.multiplayer.name = Multiplayer
|
||||
command.attack = Hyökkää
|
||||
command.rally = Kutsu Koolle
|
||||
command.retreat = Palaa
|
||||
category.multiplayer.name = Moninpeli
|
||||
command.attack = Hyökkäys
|
||||
command.rally = Kokoontuminen
|
||||
command.retreat = Perääntyminen
|
||||
placement.blockselectkeys = \n[lightgray]Key: [{0},
|
||||
keybind.clear_building.name = Clear Building
|
||||
keybind.press = Press a key...
|
||||
@ -711,7 +711,7 @@ keybind.block_select_07.name = Category/Block Select 7
|
||||
keybind.block_select_08.name = Category/Block Select 8
|
||||
keybind.block_select_09.name = Category/Block Select 9
|
||||
keybind.block_select_10.name = Category/Block Select 10
|
||||
keybind.fullscreen.name = Vaihda Fullscreen
|
||||
keybind.fullscreen.name = Vaihda kokonäyttötilaan
|
||||
keybind.select.name = Select/Shoot
|
||||
keybind.diagonal_placement.name = Diagonal Placement
|
||||
keybind.pick.name = Pick Block
|
||||
@ -722,8 +722,8 @@ keybind.zoom.name = Zoom
|
||||
keybind.menu.name = Menu
|
||||
keybind.pause.name = Pause
|
||||
keybind.pause_building.name = Pause/Resume Building
|
||||
keybind.minimap.name = Minimappi
|
||||
keybind.chat.name = Chatti
|
||||
keybind.minimap.name = Pienoiskartta
|
||||
keybind.chat.name = Keskustelu
|
||||
keybind.player_list.name = Player list
|
||||
keybind.console.name = Console
|
||||
keybind.rotate.name = Rotate
|
||||
@ -736,9 +736,9 @@ keybind.drop_unit.name = Drop Unit
|
||||
keybind.zoom_minimap.name = Zoom minimap
|
||||
mode.help.title = Description of modes
|
||||
mode.survival.name = Survival
|
||||
mode.survival.description = Normaali moodi. Rajoitettu määrä resursseja ja tasoilla on aika.\n[gray]Vaatii vihollis spawneja kartassa.
|
||||
mode.survival.description = Normaali tila. Rajoitettu määrä resursseja ja tasoilla on aika.\n[gray]Vaatii vihollisten syntymispisteen kartassa.
|
||||
mode.sandbox.name = Hiekkalaatikko
|
||||
mode.sandbox.description = Ikuisesti resursseja ja tasoilla ei ole aikaa.
|
||||
mode.sandbox.description = Ikuisesti resursseja ja tasoja ei ole ajastettu.
|
||||
mode.editor.name = Editori
|
||||
mode.pvp.name = PvP
|
||||
mode.pvp.description = Fight against other players locally.\n[gray]Requires at least 2 differently-colored cores in the map to play.
|
||||
@ -746,9 +746,9 @@ mode.attack.name = Attack
|
||||
mode.attack.description = Destroy the enemy's base. No waves.\n[gray]Requires a red core in the map to play.
|
||||
mode.custom = Custom Rules
|
||||
|
||||
rules.infiniteresources = Ikuisesti Resursseja
|
||||
rules.reactorexplosions = Reaktori Räjähdykset
|
||||
rules.wavetimer = Tasojen Aikaraja
|
||||
rules.infiniteresources = Ikuiset resurssit
|
||||
rules.reactorexplosions = Reaktorien räjähtäminen
|
||||
rules.wavetimer = Tasojen aikaraja
|
||||
rules.waves = Tasot
|
||||
rules.attack = Attack Mode
|
||||
rules.enemyCheat = Infinite AI (Red Team) Resources
|
||||
@ -791,11 +791,11 @@ item.titanium.name = Titaani
|
||||
item.thorium.name = Torium
|
||||
item.silicon.name = Pii
|
||||
item.plastanium.name = Plastaniumi
|
||||
item.phase-fabric.name = Kiihde Kuitu
|
||||
item.surge-alloy.name = Taite Seos
|
||||
item.spore-pod.name = Itiö Palko
|
||||
item.phase-fabric.name = Kiihdekuitu
|
||||
item.surge-alloy.name = Taiteseos
|
||||
item.spore-pod.name = Itiöpalko
|
||||
item.sand.name = Hiekka
|
||||
item.blast-compound.name = Räjähde Yhdiste
|
||||
item.blast-compound.name = Räjähdeyhdiste
|
||||
item.pyratite.name = Pyratiitti
|
||||
item.metaglass.name = Metallilasi
|
||||
item.scrap.name = Romu
|
||||
@ -824,7 +824,7 @@ mech.trident-ship.name = Trident
|
||||
mech.trident-ship.weapon = Bomb Bay
|
||||
mech.glaive-ship.name = Glaive
|
||||
mech.glaive-ship.weapon = Flame Repeater
|
||||
item.corestorable = [lightgray]Säilöttävissä Ytimeen: {0}
|
||||
item.corestorable = [lightgray]Säilöttävissä ytimeen: {0}
|
||||
item.explosiveness = [lightgray]Räjädysmäisyys: {0}%
|
||||
item.flammability = [lightgray]Flammability: {0}%
|
||||
item.radioactivity = [lightgray]Radioactivity: {0}%
|
||||
@ -832,12 +832,12 @@ unit.health = [lightgray]Elämäpisteet: {0}
|
||||
unit.speed = [lightgray]Nopeus: {0}
|
||||
mech.weapon = [lightgray]Ase: {0}
|
||||
mech.health = [lightgray]Elämäpisteet: {0}
|
||||
mech.itemcapacity = [lightgray]Tavara Kapasiteetti: {0}
|
||||
mech.minespeed = [lightgray]Louhimis Nopeus: {0}%
|
||||
mech.minepower = [lightgray]Louhimis Voima: {0}
|
||||
mech.ability = [lightgray]Spesiaalikyky: {0}
|
||||
mech.buildspeed = [lightgray]Rakennus Nopeus: {0}%
|
||||
liquid.heatcapacity = [lightgray]Lämpö Kapasiteetti: {0}
|
||||
mech.itemcapacity = [lightgray]Tavarakapasiteetti: {0}
|
||||
mech.minespeed = [lightgray]Louhimisnopeus: {0}%
|
||||
mech.minepower = [lightgray]Louhimisvoima: {0}
|
||||
mech.ability = [lightgray]Erityiskyky: {0}
|
||||
mech.buildspeed = [lightgray]Rakentamisnopeus: {0}%
|
||||
liquid.heatcapacity = [lightgray]Lämpökapasiteetti: {0}
|
||||
liquid.viscosity = [lightgray]Tahmeus: {0}
|
||||
liquid.temperature = [lightgray]Lämpö: {0}
|
||||
|
||||
@ -865,21 +865,21 @@ block.scrap-wall-huge.name = Huge Scrap Wall
|
||||
block.scrap-wall-gigantic.name = Gigantic Scrap Wall
|
||||
block.thruster.name = Thruster
|
||||
block.kiln.name = Kiln
|
||||
block.graphite-press.name = Grafiitti Puristin
|
||||
block.multi-press.name = Multi-Puristin
|
||||
block.graphite-press.name = Grafiittipuristin
|
||||
block.multi-press.name = Monipuristin
|
||||
block.constructing = {0} [lightgray](Rakentamassa)
|
||||
block.spawn.name = Vihollis Spawni
|
||||
block.spawn.name = Vihollisten syntymispiste
|
||||
block.core-shard.name = Ydin: Siru
|
||||
block.core-foundation.name = Ydin: Pohjaus
|
||||
block.core-nucleus.name = Ydin: Tuma
|
||||
block.deepwater.name = Syvä Vesi
|
||||
block.deepwater.name = Syvä vesi
|
||||
block.water.name = Vesi
|
||||
block.tainted-water.name = Pilattu Vesi
|
||||
block.tainted-water.name = Pilaantunut vesi
|
||||
block.darksand-tainted-water.name = Dark Sand Tainted Water
|
||||
block.tar.name = Terva
|
||||
block.stone.name = Kivi
|
||||
block.sand.name = Hiekka
|
||||
block.darksand.name = Tumma Hiekka
|
||||
block.darksand.name = Tumma hiekka
|
||||
block.ice.name = Jää
|
||||
block.snow.name = Lumi
|
||||
block.craters.name = Kraatterit
|
||||
|
@ -172,8 +172,13 @@ hosts.discovering.any = Ricerca partite
|
||||
server.refreshing = Aggiornamento del server
|
||||
hosts.none = [lightgray]Nessuna partita locale trovata!
|
||||
host.invalid = [scarlet]Impossibile connettersi all'host.
|
||||
trace = Traccia giocatore
|
||||
trace.playername = Nome del giocatore: [accent]{0}
|
||||
|
||||
servers.local = Server Locali
|
||||
servers.remote = Server Remoti
|
||||
servers.global = Server Globali
|
||||
|
||||
trace = Traccia Giocatore
|
||||
trace.playername = Nome del Giocatore: [accent]{0}
|
||||
trace.ip = IP: [accent]{0}
|
||||
trace.id = ID univoco: [accent]{0}
|
||||
trace.mobile = Client Mobile: [accent]{0}
|
||||
@ -183,11 +188,11 @@ server.bans = Lista Bans
|
||||
server.bans.none = Nessun giocatore bandito trovato!
|
||||
server.admins = Amministratori
|
||||
server.admins.none = Nessun amministratore trovato!
|
||||
server.add = Aggiungi server
|
||||
server.add = Aggiungi Server
|
||||
server.delete = Sei sicuro di voler eliminare questo server?
|
||||
server.edit = Modifica server
|
||||
server.outdated = [crimson]Server obsoleto![]
|
||||
server.outdated.client = [crimson]Client obsoleto![]
|
||||
server.edit = Modifica Server
|
||||
server.outdated = [crimson]Server Obsoleto![]
|
||||
server.outdated.client = [crimson]Client Obsoleto![]
|
||||
server.version = [gray]v{0} {1}
|
||||
server.custombuild = [yellow]Build Personalizzata
|
||||
confirmban = Sei sicuro di voler bandire questo giocatore?
|
||||
|
@ -59,7 +59,7 @@ public class Blocks implements ContentList{
|
||||
//transport
|
||||
conveyor, titaniumConveyor, plastaniumConveyor, armoredConveyor, distributor, junction, itemBridge, phaseConveyor, sorter, invertedSorter, router, overflowGate, underflowGate, massDriver,
|
||||
|
||||
//liquids
|
||||
//liquid
|
||||
mechanicalPump, rotaryPump, thermalPump, conduit, pulseConduit, platedConduit, liquidRouter, liquidTank, liquidJunction, bridgeConduit, phaseConduit,
|
||||
|
||||
//power
|
||||
|
@ -1,231 +0,0 @@
|
||||
package mindustry.entities.def;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.Bits;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import arc.util.pooling.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.ctype.*;
|
||||
import mindustry.entities.bullet.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static mindustry.Vars.content;
|
||||
|
||||
public class EntityComps{
|
||||
|
||||
@Depends({HealthComp.class, VelComp.class, StatusComp.class})
|
||||
class UnitComp{
|
||||
|
||||
}
|
||||
|
||||
class OwnerComp{
|
||||
Entityc owner;
|
||||
}
|
||||
|
||||
@Depends({TimedComp.class})
|
||||
class BulletComp{
|
||||
BulletType bullet;
|
||||
|
||||
void init(){
|
||||
bullet.init();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TimedComp extends EntityComp implements Scaled{
|
||||
float time, lifetime;
|
||||
|
||||
void update(){
|
||||
time = Math.min(time + Time.delta(), lifetime);
|
||||
|
||||
if(time >= lifetime){
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float fin(){
|
||||
return time / lifetime;
|
||||
}
|
||||
}
|
||||
|
||||
class HealthComp{
|
||||
float health, maxHealth;
|
||||
boolean dead;
|
||||
|
||||
float healthf(){
|
||||
return health / maxHealth;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class PosComp implements Position{
|
||||
float x, y;
|
||||
|
||||
void set(float x, float y){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
@Depends(PosComp.class)
|
||||
class VelComp{
|
||||
//transient fields act as imports from any other component clases; these are ignored by the generator
|
||||
transient float x, y;
|
||||
|
||||
final Vec2 vel = new Vec2();
|
||||
|
||||
void update(){
|
||||
x += vel.x;
|
||||
y += vel.y;
|
||||
vel.scl(0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
@Depends(PosComp.class)
|
||||
class HitboxComp{
|
||||
transient float x, y;
|
||||
|
||||
float hitSize;
|
||||
|
||||
boolean collides(Hitboxc other){
|
||||
return Intersector.overlapsRect(x - hitSize/2f, y - hitSize/2f, hitSize, hitSize,
|
||||
other.getX() - other.getHitSize()/2f, other.getY() - other.getHitSize()/2f, other.getHitSize(), other.getHitSize());
|
||||
}
|
||||
}
|
||||
|
||||
@Depends(PosComp.class)
|
||||
class StatusComp{
|
||||
private Array<StatusEntry> statuses = new Array<>();
|
||||
private Bits applied = new Bits(content.getBy(ContentType.status).size);
|
||||
|
||||
private float speedMultiplier;
|
||||
private float damageMultiplier;
|
||||
private float armorMultiplier;
|
||||
|
||||
void apply(StatusEffect effect, float duration){
|
||||
if(effect == StatusEffects.none || effect == null || isImmune(effect)) return; //don't apply empty or immune effects
|
||||
|
||||
if(statuses.size > 0){
|
||||
//check for opposite effects
|
||||
for(StatusEntry entry : statuses){
|
||||
//extend effect
|
||||
if(entry.effect == effect){
|
||||
entry.time = Math.max(entry.time, duration);
|
||||
return;
|
||||
}else if(entry.effect.reactsWith(effect)){ //find opposite
|
||||
StatusEntry.tmp.effect = entry.effect;
|
||||
//TODO unit cannot be null here
|
||||
entry.effect.getTransition(null, effect, entry.time, duration, StatusEntry.tmp);
|
||||
entry.time = StatusEntry.tmp.time;
|
||||
|
||||
if(StatusEntry.tmp.effect != entry.effect){
|
||||
entry.effect = StatusEntry.tmp.effect;
|
||||
}
|
||||
|
||||
//stop looking when one is found
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, no opposites found, add direct effect
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
|
||||
entry.set(effect, duration);
|
||||
statuses.add(entry);
|
||||
}
|
||||
|
||||
boolean isImmune(StatusEffect effect){
|
||||
return false;
|
||||
}
|
||||
|
||||
Color getStatusColor(){
|
||||
if(statuses.size == 0){
|
||||
return Tmp.c1.set(Color.white);
|
||||
}
|
||||
|
||||
float r = 0f, g = 0f, b = 0f;
|
||||
for(StatusEntry entry : statuses){
|
||||
r += entry.effect.color.r;
|
||||
g += entry.effect.color.g;
|
||||
b += entry.effect.color.b;
|
||||
}
|
||||
return Tmp.c1.set(r / statuses.size, g / statuses.size, b / statuses.size, 1f);
|
||||
}
|
||||
|
||||
void update(){
|
||||
applied.clear();
|
||||
speedMultiplier = damageMultiplier = armorMultiplier = 1f;
|
||||
|
||||
if(statuses.isEmpty()) return;
|
||||
|
||||
statuses.eachFilter(entry -> {
|
||||
entry.time = Math.max(entry.time - Time.delta(), 0);
|
||||
applied.set(entry.effect.id);
|
||||
|
||||
if(entry.time <= 0){
|
||||
Pools.free(entry);
|
||||
return true;
|
||||
}else{
|
||||
speedMultiplier *= entry.effect.speedMultiplier;
|
||||
armorMultiplier *= entry.effect.armorMultiplier;
|
||||
damageMultiplier *= entry.effect.damageMultiplier;
|
||||
//TODO unit can't be null
|
||||
entry.effect.update(null, entry.time);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
boolean hasEffect(StatusEffect effect){
|
||||
return applied.get(effect.id);
|
||||
}
|
||||
|
||||
void writeSave(DataOutput stream) throws IOException{
|
||||
stream.writeByte(statuses.size);
|
||||
for(StatusEntry entry : statuses){
|
||||
stream.writeByte(entry.effect.id);
|
||||
stream.writeFloat(entry.time);
|
||||
}
|
||||
}
|
||||
|
||||
void readSave(DataInput stream, byte version) throws IOException{
|
||||
for(StatusEntry effect : statuses){
|
||||
Pools.free(effect);
|
||||
}
|
||||
|
||||
statuses.clear();
|
||||
|
||||
byte amount = stream.readByte();
|
||||
for(int i = 0; i < amount; i++){
|
||||
byte id = stream.readByte();
|
||||
float time = stream.readFloat();
|
||||
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
|
||||
entry.set(content.getByID(ContentType.status, id), time);
|
||||
statuses.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BaseComponent
|
||||
class EntityComp{
|
||||
int id;
|
||||
|
||||
void init(){}
|
||||
|
||||
void update(){}
|
||||
|
||||
void remove(){}
|
||||
|
||||
<T> T as(Class<T> type){
|
||||
return (T)this;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package mindustry.entities.def;
|
||||
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.def.EntityComps.*;
|
||||
|
||||
class EntityDefs{
|
||||
|
||||
@EntityDef({BulletComp.class, VelComp.class, TimedComp.class})
|
||||
class BulletDef{}
|
||||
}
|
@ -100,6 +100,8 @@ public class MusicControl{
|
||||
/** Plays and fades in a music track. This must be called every frame.
|
||||
* If something is already playing, fades out that track and fades in this new music.*/
|
||||
private void play(@Nullable Music music){
|
||||
if(!shouldPlay()) return;
|
||||
|
||||
//update volume of current track
|
||||
if(current != null){
|
||||
current.setVolume(fade * Core.settings.getInt("musicvol") / 100f);
|
||||
@ -143,7 +145,7 @@ public class MusicControl{
|
||||
|
||||
/** Plays a music track once and only once. If something is already playing, does nothing.*/
|
||||
private void playOnce(Music music){
|
||||
if(current != null || music == null) return; //do not interrupt already-playing tracks
|
||||
if(current != null || music == null || !shouldPlay()) return; //do not interrupt already-playing tracks
|
||||
|
||||
//save last random track played to prevent duplicates
|
||||
lastRandomPlayed = music;
|
||||
@ -162,6 +164,10 @@ public class MusicControl{
|
||||
current.play();
|
||||
}
|
||||
|
||||
private boolean shouldPlay(){
|
||||
return Core.settings.getInt("musicvol") > 0;
|
||||
}
|
||||
|
||||
/** Fades out the current track, unless it has already been silenced. */
|
||||
private void silence(){
|
||||
play(null);
|
||||
|
@ -375,7 +375,7 @@ public class Schematics implements Loadable{
|
||||
/** Loads a schematic from base64. May throw an exception. */
|
||||
public static Schematic readBase64(String schematic){
|
||||
try{
|
||||
return read(new ByteArrayInputStream(Base64Coder.decode(schematic)));
|
||||
return read(new ByteArrayInputStream(Base64Coder.decode(schematic.trim())));
|
||||
}catch(IOException e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -611,7 +611,7 @@ public class Mods implements Loadable{
|
||||
|
||||
Fi metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("mod.hjson").exists() ? zip.child("mod.hjson") : zip.child("plugin.json");
|
||||
if(!metaf.exists()){
|
||||
Log.warn("Mod {0} doesn't have a 'mod.json'/'plugin.json'/'mod.js' file, skipping.", sourceFile);
|
||||
Log.warn("Mod {0} doesn't have a 'mod.json'/'mod.hjson'/'plugin.json' file, skipping.", sourceFile);
|
||||
throw new IllegalArgumentException("No mod.json found.");
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ public class ItemsDisplay extends Table{
|
||||
t.setText(state.is(State.menu) ? "$launcheditems" : "$launchinfo");
|
||||
t.setChecked(col.isCollapsed());
|
||||
((Image)t.getChildren().get(1)).setDrawable(col.isCollapsed() ? Icon.upOpen : Icon.downOpen);
|
||||
}).padBottom(4).left().fillX().margin(12f);
|
||||
}).padBottom(4).left().fillX().margin(12f).minWidth(200f);
|
||||
c.row();
|
||||
c.add(col);
|
||||
});
|
||||
|
@ -24,7 +24,6 @@ public class Junction extends Block{
|
||||
super(name);
|
||||
update = true;
|
||||
solid = true;
|
||||
instantTransfer = true;
|
||||
group = BlockGroup.transportation;
|
||||
unloadable = false;
|
||||
entityType = JunctionEntity::new;
|
||||
|
@ -39,7 +39,6 @@ public class LiquidExtendingBridge extends ExtendingItemBridge{
|
||||
}
|
||||
|
||||
if(entity.uptime >= 0.5f){
|
||||
|
||||
if(tryMoveLiquid(tile, other, false, entity.liquids.current()) > 0.1f){
|
||||
entity.cycleSpeed = Mathf.lerpDelta(entity.cycleSpeed, 4f, 0.05f);
|
||||
}else{
|
||||
|
@ -139,7 +139,7 @@ public class GenericCrafter extends Block{
|
||||
if(outputItem != null && tile.entity.items.get(outputItem.item) >= itemCapacity){
|
||||
return false;
|
||||
}
|
||||
return outputLiquid == null || !(tile.entity.liquids.get(outputLiquid.liquid) >= liquidCapacity);
|
||||
return outputLiquid == null || !(tile.entity.liquids.get(outputLiquid.liquid) >= liquidCapacity - 0.001f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,3 +1,3 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||
archash=a57e709113a364ff718821de4c40366e17353329
|
||||
archash=b2996f736d5b6870913f5d8b5496fe6033069ac8
|
||||
|
Reference in New Issue
Block a user