Merge branch 'master' into balancing-payload_system
This commit is contained in:
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2448,7 +2449,7 @@ unit.collaris.description = Fires long-range fragmenting artillery at enemy targ
|
||||
unit.elude.description = Fires pairs of homing bullets at enemy targets. Can float over bodies of liquid.
|
||||
unit.avert.description = Fires twisting pairs of bullets at enemy targets.
|
||||
unit.obviate.description = Fires twisting pairs of lightning orbs at enemy targets.
|
||||
unit.quell.description = Fires long-range homing missiles at enemy targets. Suppresses enemy structure repair blocks. Only attacks ground targets.
|
||||
unit.quell.description = Fires long-range homing missiles with unstable plasma shielding at enemy targets. Suppresses enemy structure repair blocks. Only attacks ground targets.
|
||||
unit.disrupt.description = Fires long-range homing suppression missiles at enemy targets. Suppresses enemy structure repair blocks. Only attacks ground targets.
|
||||
unit.evoke.description = Builds structures to defend the Bastion core. Repairs structures with a beam. Capable of carrying 2x2 structures.
|
||||
unit.incite.description = Builds structures to defend the Citadel core. Repairs structures with a beam. Capable of carrying 2x2 structures.
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Хваля:
|
||||
sectors.stored = Захавана:
|
||||
sectors.resume = Працягнуць
|
||||
sectors.launch = Запусціць
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Выбраць
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]нічога (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Вълна:
|
||||
sectors.stored = Съхранени:
|
||||
sectors.resume = Продължи
|
||||
sectors.launch = Изстреляй
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Избери
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]няма (Слънцето)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID на единица/блок/предмет/течност.\nТ
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Неизвестно
|
||||
lcategory.unknown.description = Некатегоризирани указания.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Винаги вярно
|
||||
lenum.idiv = Деление с цели числа.
|
||||
lenum.div = Деление.\nВръща [accent]null[] при делене на 0.
|
||||
lenum.mod = Модул.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Равенство. Конвертира променливите в еднакъв тип.\nНе-null обекти стават 1, null обекти стават 0.
|
||||
lenum.notequal = Неравенство. Конвертира променливите в еднакъв тип.
|
||||
lenum.strictequal = Стриктно равенство. Отрицателно при различни типове променливи.\nМоже да се използва за проверка на [accent]null[].
|
||||
lenum.shl = Побитово изместване наляво.
|
||||
lenum.shr = Побитово изместване надясно.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Побитово ИЛИ.
|
||||
lenum.land = Логическо И.
|
||||
lenum.and = Побитово И.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Onada:
|
||||
sectors.stored = Emmagatzemat:
|
||||
sectors.resume = Continua
|
||||
sectors.launch = Llança
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Selecciona
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]cap (sol)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = Identificador d’unitat/bloc/element/líquid.\nÉs l’invers de l
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Desconegut
|
||||
lcategory.unknown.description = Instruccions sense categoria.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Sempre cert.
|
||||
lenum.idiv = Divisió entera.
|
||||
lenum.div = Divisió.\nRetorna [accent]null[] si es divideix per zero.
|
||||
lenum.mod = Mòdul (residu de la divisió entera).
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Igual. Força els tipus.\nCompara objectes no nuls amb nombres. Si són iguals, retorna 1. Si no, retorna 0.
|
||||
lenum.notequal = No igual. Força els tipus.
|
||||
lenum.strictequal = Igualtat estricta sense forçar el tipus.\nEs pot fer servir amb objectes nuls.
|
||||
lenum.shl = Desplaça els bits a l’esquerra.
|
||||
lenum.shr = Desplaça els bits a la dreta.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Operació lògica OR bit a bit.
|
||||
lenum.land = Operació lògica AND bit a bit.
|
||||
lenum.and = Operació lògica AND bit a bit.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Vlna:
|
||||
sectors.stored = Uskladněno:
|
||||
sectors.resume = Pokračovat
|
||||
sectors.launch = Vyslat
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Vybrat
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]bez (slunce)[]
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Šířka displeje v pixelech.
|
||||
laccess.displayheight = Výška displeje v pixelech.
|
||||
laccess.bufferusage = Počet nezpracovaných příkazů ve vyrovnávací paměti displeje.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Neznámé
|
||||
lcategory.unknown.description = Nezařazené instrukce.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Vždy pravda.
|
||||
lenum.idiv = Číselné dělení.
|
||||
lenum.div = Dělení.\nVrací [accent]null[], pokud je děleno nulou.
|
||||
lenum.mod = Modulo (Vydělí 2 hodnoty a vrací zbytek).
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Stejné. Vynucuje typy.\nNon-null objekty porovnané s čísly se stanou 1, jinak 0.
|
||||
lenum.notequal = Není stejné. Vynucuje typy.
|
||||
lenum.strictequal = Přísná rovnost. Nevynucuje typy.\nMůže být použít, jestli je [accent]null[].
|
||||
lenum.shl = Bitový posun vlevo.
|
||||
lenum.shr = Bitový posun vpravo.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitový OR.
|
||||
lenum.land = Logický AND.
|
||||
lenum.and = Bitový AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Genoptag
|
||||
sectors.launch = Affyr
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Vælg
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]ingen (solen)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Welle:
|
||||
sectors.stored = Gelagert:
|
||||
sectors.resume = Weiterspielen
|
||||
sectors.launch = Start
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Auswählen
|
||||
sectors.launchselect = Ziel auswählen
|
||||
sectors.nonelaunch = [lightgray]keiner (Sonne)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID einer Einheit/eines Blocks/eines Materials/einer Flüssigkeit\nT
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unbekannt
|
||||
lcategory.unknown.description = Unbekannte Anweisungen
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Immer.
|
||||
lenum.idiv = Division mit ganzen Zahlen.
|
||||
lenum.div = Division.\nGibt bei Teilung durch null [accent]null[] zurück.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Prüft Gleichheit.\nNicht-null Objekte, die mit Zahlen verglichen werden, werden 1.
|
||||
lenum.notequal = Prüft Ungleichheit.
|
||||
lenum.strictequal = Prüft strenge Gleichheit.\nKann verwendet werden, um [accent]null[] zu finden.
|
||||
lenum.shl = Bit-Shift nacht links.
|
||||
lenum.shr = Bit-Shift nach rechts.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise ODER.
|
||||
lenum.land = Logisches AND.
|
||||
lenum.and = Bitweises UND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Oleada:
|
||||
sectors.stored = Almacenado:
|
||||
sectors.resume = Reanudar
|
||||
sectors.launch = Lanzar
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Seleccionar
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]Ninguno (sol)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Desconocido
|
||||
lcategory.unknown.description = Instrucciones no clasificadas.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Siempre "true".
|
||||
lenum.idiv = División de un número entero.
|
||||
lenum.div = División.\nDevuelve [accent]null[] al dividir entre cero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Igual. Coacciona tipos.\nObjetos no-nulos coaccionados con números pasan a 1, si no coinciden pasan a 0.
|
||||
lenum.notequal = No igual. Coacciona tipos.
|
||||
lenum.strictequal = Igualdad estricta. No coacciona tipos.\nSe puede usar para comprobar si un resultado es [accent]null[].
|
||||
lenum.shl = Cambia bits a izquierda.
|
||||
lenum.shr = Cambia bits a derecha.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Comprobación bit a bit OR.
|
||||
lenum.land = Comprobación lógica AND.
|
||||
lenum.and = Comprobación bit a bit AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Taso:
|
||||
sectors.stored = Säilötty:
|
||||
sectors.resume = Jatka
|
||||
sectors.launch = Laukaise
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Valitse
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]ei mitään (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Tuntematon
|
||||
lcategory.unknown.description = Luokittelemattomat ohjeet.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Aina tosi.
|
||||
lenum.idiv = Kokonaislukujen osamäärä.
|
||||
lenum.div = Osamäärä.\nPalauttaa arvon [accent]null[] jaettaessa nollalla.
|
||||
lenum.mod = Lukuun ottamatta.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Yhtä suuri. Pakottaa tyypit.\nMuut kohteet kuin null palauttavat arvon 1 verrattaessa numeroihin, muussa tapauksessa palautus on 0.
|
||||
lenum.notequal = Erisuuri. Pakottaa tyypit.
|
||||
lenum.strictequal = Tarkka yhtäsuuruus. Ei pakota tyyppejä.\nVoidaan käyttää tarkistamaan arvon [accent]null[] varalta.
|
||||
lenum.shl = Siirrä bittejä vasemmalle.
|
||||
lenum.shr = Siirrä bittejä oikealle.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Binäärinen OR.
|
||||
lenum.land = Looginen AND.
|
||||
lenum.and = Binäärinen AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Mga Waves:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = I-Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = I-Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Vague :
|
||||
sectors.stored = Stockage :
|
||||
sectors.resume = Reprendre
|
||||
sectors.launch = Décoller
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Sélectionner
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]Vide (soleil)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = L'ID d'une unité/bloc/ressource/liquide.\nCeci est l'inverse de l'
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Inconnu
|
||||
lcategory.unknown.description = Instructions sans catégorie.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Toujours [accent]true[].
|
||||
lenum.idiv = Division entière.
|
||||
lenum.div = Division.\nRetourne [accent]null[] lors d'une division par zéro.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Égalité. Conversion des types.\nLes objets non-nuls comparés avec des nombres deviennent 1, sinon 0.
|
||||
lenum.notequal = Inégalité. Conversion des types.
|
||||
lenum.strictequal = Égalité stricte. Ne convertit pas les types.\nPeut être utilisé pour vérifier les valeurs [accent]null[].
|
||||
lenum.shl = Décalage de bits vers la gauche.
|
||||
lenum.shr = Décalage de bits vers la droite.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Opération binaire OR.
|
||||
lenum.land = Opération logique AND.
|
||||
lenum.and = Opération binaire AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Hullám:
|
||||
sectors.stored = Tárolt nyersanyagok:
|
||||
sectors.resume = Folytatás
|
||||
sectors.launch = Kilövés
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Kiválasztás
|
||||
sectors.launchselect = Célállomás kiválasztása
|
||||
sectors.nonelaunch = [lightgray]semmi (nap)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = Egy egység/blokk/nyersanyag/folyadék azonosítója.\nEz a keresé
|
||||
laccess.displaywidth = Egy kijelzőblokk szélessége pixelben.
|
||||
laccess.displayheight = Egy kijelzőblokk magassága pixelben.
|
||||
laccess.bufferusage = A kijelző grafikus pufferében lévő feldolgozatlan parancsok száma.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Ismeretlen
|
||||
lcategory.unknown.description = Nem kategorizált utasítások.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Mindig igaz.
|
||||
lenum.idiv = Egész osztás.
|
||||
lenum.div = Osztás.\nNullával való osztáskor a visszatérési érték [accent]null[].
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Egyenlő. Kényszeríti a típusokat.\nA nem null értékű objektumok értéke 1 lesz, egyébként 0.
|
||||
lenum.notequal = Nem egyenlő. Kényszeríti a típusokat.
|
||||
lenum.strictequal = Szigorúan egyenlőség. Nem kényszeríti a típusokat.\nA [accent]null[] ellenőrzésére is használható.
|
||||
lenum.shl = Biteltolás balra.
|
||||
lenum.shr = Biteltolás jobbra.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitenkénti VAGY.
|
||||
lenum.land = Logikai ÉS.
|
||||
lenum.and = Bitenkénti ÉS.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Gelombang:
|
||||
sectors.stored = Terisi:
|
||||
sectors.resume = Lanjutkan
|
||||
sectors.launch = Luncurkan
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Pilih
|
||||
sectors.launchselect = Pilih Destinasi Peluncuran
|
||||
sectors.nonelaunch = [lightgray]tidak ada (matahari)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID suatu unit/blok/bahan/cairan.\nIni adalah kebalikan dari operasi
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Tak Diketahui
|
||||
lcategory.unknown.description = Instruksi tanpa kategori.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Selalu benar.
|
||||
lenum.idiv = Pembagian integer.
|
||||
lenum.div = Pembagian.\nMengembalikan [accent]null[] pada pembagian dengan nol.
|
||||
lenum.mod = Modulus.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Kesetaraan. Mengonversikan tipe.\nObjek bukan nol dibandingkan dengan angka menjadi 1, jika tidak 0.
|
||||
lenum.notequal = Kesetaraan tanpa jenis pemaksaan. Mengonversikan tipe.
|
||||
lenum.strictequal = Kesetaraan dengan jenis pemaksaan. Tidak mengonversikan tipe.\nDapat digunakan untuk memeriksa [accent]null[].
|
||||
lenum.shl = Bit-shift kiri.
|
||||
lenum.shr = Bit-shift kanan.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logika AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Ondata:
|
||||
sectors.stored = Immagazzinato:
|
||||
sectors.resume = Riprendi
|
||||
sectors.launch = Lancia
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Seleziona
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]nessuno (sole)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = ウェーブ:
|
||||
sectors.stored = コアの資源:
|
||||
sectors.resume = 再開
|
||||
sectors.launch = 打ち上げ
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = 選択
|
||||
sectors.launchselect = 発射先
|
||||
sectors.nonelaunch = [lightgray]無し (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = 不明
|
||||
lcategory.unknown.description = 未分類の指示です。
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = 常にtrueを返します。
|
||||
lenum.idiv = 整数の割り算をします。
|
||||
lenum.div = 割り算をします。\nゼロ除算で [accent]null[] を返します。
|
||||
lenum.mod = 割ったあまりを返します。
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = 等しいかどうかを比較します。型を強制します。\n数値と比較される非NULLオブジェクトは1になり、そうでない場合は0になる。
|
||||
lenum.notequal = 等しくないかどうかを比較します。型を強制します。
|
||||
lenum.strictequal = より厳密な比較をします。型の強制はしません。\n [accent]null[] のチェックに使用することができます。
|
||||
lenum.shl = ビットを左にシフトします。
|
||||
lenum.shr = ビットを右にシフトします。
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = ビット単位でのOR演算をします。
|
||||
lenum.land = 論理的なAND演算をします。
|
||||
lenum.and = ビット単位でのAND演算をします。
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = 단계:
|
||||
sectors.stored = 저장량:
|
||||
sectors.resume = 재개
|
||||
sectors.launch = 출격
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = 선택
|
||||
sectors.launchselect = 발사 대상 선택
|
||||
sectors.nonelaunch = [lightgray]없음 (태양)[]
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = 유닛/블록/아이템/액체의 ID.\n이것은 조회 작업의
|
||||
laccess.displaywidth = 디스플레이 블록의 픽셀 단위 너비.
|
||||
laccess.displayheight = 디스플레이 블록의 픽셀 단위 높이.
|
||||
laccess.bufferusage = 디스플레이의 그래픽 버퍼에 있는 처리되지 않은 명령의 수.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = 알 수 없음
|
||||
lcategory.unknown.description = 분류되지 않은 설명
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = 항상 참
|
||||
lenum.idiv = 정수 나누기
|
||||
lenum.div = 나누기\n0으로 나누면 [accent]null[]을 반환합니다.
|
||||
lenum.mod = 나머지
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = 동치 비교. 형변환 가능\nNull이 아닌 객체가 숫자와 비교하려면 1이 되고, 아니면 0이 됩니다.
|
||||
lenum.notequal = 동치 부정. 형변환 가능
|
||||
lenum.strictequal = 엄격한 동치 비교. 형변환 불가능\n[accent]null[]을 확인할 때 쓸 수 있습니다.
|
||||
lenum.shl = 왼쪽으로 비트 이동
|
||||
lenum.shr = 오른쪽으로 비트 이동
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = 비트연산자 OR
|
||||
lenum.land = 논리연산자 AND
|
||||
lenum.and = 비트연산자 AND
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Golf:
|
||||
sectors.stored = Opgeslagen:
|
||||
sectors.resume = Doorgaan
|
||||
sectors.launch = Lanceer
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Selecteer
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]geen (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Fala:
|
||||
sectors.stored = Zmagazynowane:
|
||||
sectors.resume = Kontynuuj
|
||||
sectors.launch = Wystrzel
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Wybierz
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]Żaden (Słońce)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID jednostki/bloku/przedmiotu/płynu.\nOdwrotnośc operacji wyszuki
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Inne
|
||||
lcategory.unknown.description = Niezkategoryzowane instrukcje.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Zawsze prawda.
|
||||
lenum.idiv = Dzielenie liczb całkowitych.
|
||||
lenum.div = Dzielenie.\nZwraca [accent]null[] w trakcie dzielenia przez zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Równość. Wymusza typ.\nNiezerowe objekty połączone z liczbami stają się 1, w innym wypadku 0.
|
||||
lenum.notequal = Nierówność. Wymusza typ.
|
||||
lenum.strictequal = Ścisła równość. Nie wymusza typów.\nMoże być użyte do wykrycia [accent]null[].
|
||||
lenum.shl = Przesunięcie bitowe w lewo.
|
||||
lenum.shr = Przesunięcie bitowe w prawo.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitowe OR (lub).
|
||||
lenum.land = Logiczne AND (i).
|
||||
lenum.and = Bitowe AND (i).
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Horda:
|
||||
sectors.stored = Armazenado:
|
||||
sectors.resume = Continuar
|
||||
sectors.launch = Lançar
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Selecionar
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]nenhum (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Desconhecido
|
||||
lcategory.unknown.description = Instruções não categorizadas.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Sempre verdade.
|
||||
lenum.idiv = Divisão inteira.
|
||||
lenum.div = Divisão.\nRetorna [accent]null[] na divisão por zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Igual. Coage tipos.\nObjetos não nulos comparados com números tornam-se 1, caso contrário, 0.
|
||||
lenum.notequal = Não igual. Tipos de coerção.
|
||||
lenum.strictequal = Igualdade estrita. Não coage tipos.Pode ser usado para verificar [accent]null[].
|
||||
lenum.shl = Deslocamento de bit para a esquerda.
|
||||
lenum.shr = Deslocamento de bits para a direita.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = OU bit a bit.
|
||||
lenum.land = Lógico E.
|
||||
lenum.and = E bit a bit.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Horda:
|
||||
sectors.stored = Armazenado:
|
||||
sectors.resume = Continuar
|
||||
sectors.launch = Lançar
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Selecionar
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]nenhum (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Desconhecido
|
||||
lcategory.unknown.description = Instruções não categorizadas.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Sempre verdade.
|
||||
lenum.idiv = Divisão inteira.
|
||||
lenum.div = Divisão.\nRetorna [accent]null[] na divisão por zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Igual. Coage tipos.\nObjetos não nulos comparados com números tornam-se 1, caso contrário, 0.
|
||||
lenum.notequal = Não igual. Tipos de coerção.
|
||||
lenum.strictequal = Igualdade estrita. Não coage tipos.Pode ser usado para verificar [accent]null[].
|
||||
lenum.shl = Deslocamento de bit para a esquerda.
|
||||
lenum.shr = Deslocamento de bits para a direita.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = OU bit a bit.
|
||||
lenum.land = Lógico E.
|
||||
lenum.and = E bit a bit.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Valul:
|
||||
sectors.stored = Stocat:
|
||||
sectors.resume = Revino
|
||||
sectors.launch = Lansare
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Selectează
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]nimic (soarele)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Mereu adevărat.
|
||||
lenum.idiv = Împărțirea naturală a numerelor (int).
|
||||
lenum.div = Împărțirea.\nReturnează [accent]null[] dacă împarți la 0.
|
||||
lenum.mod = Modulo (restul împărțirii).
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Egal. Convertește tipurile variabilelor.\nObiectele nenule comparate cu numere devin 1, cele nule devin 0.
|
||||
lenum.notequal = Nu e egal. Convertește tipurile variabilelor.
|
||||
lenum.strictequal = Egalitate strictă. Nu convertește tipurile variabilelor.\nPoate fi folosit pt a verifica dacă ceva este [accent]null[].
|
||||
lenum.shl = Shift left pe biți.
|
||||
lenum.shr = Shift right pe biți.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = OR/SAU. Ține cont de biți.
|
||||
lenum.land = Logical AND/ȘI logic. Nu ține cont de biți.
|
||||
lenum.and = AND/ȘI. Ține cont de biți.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Волна:
|
||||
sectors.stored = Накоплено:
|
||||
sectors.resume = Продолжить
|
||||
sectors.launch = Высадка
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Выбор
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]нет (солнце)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = Идентификатор единицы/блока/предмет
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Неизвестно
|
||||
lcategory.unknown.description = Нет категории.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Всегда истина.
|
||||
lenum.idiv = Целочисленное деление.
|
||||
lenum.div = Деление.\nВозвращает [accent]null[] при делении на ноль.
|
||||
lenum.mod = Остаток от деления.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Равно. Приводит типы.\nНе-null объекты, по сравнению с числами, становятся 1, иначе — 0.
|
||||
lenum.notequal = Не равно. Приводит типы.
|
||||
lenum.strictequal = Строгое равенство. Не приводит типы.\nМожет быть использовано для проверки на [accent]null[].
|
||||
lenum.shl = Побитовый сдвиг влево.
|
||||
lenum.shr = Побитовый сдвиг вправо.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Побитовое ИЛИ.
|
||||
lenum.land = Булевое И.
|
||||
lenum.and = Побитовое И.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Talas:
|
||||
sectors.stored = Skladišćeno:
|
||||
sectors.resume = Nastavi
|
||||
sectors.launch = Lansiraj
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Izaberi
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]nema (sunce)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Nepoznato
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Uvek Tačno.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Deljenje.Šalje [accent]null[] kada se deli sa nulom.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Jednakost. Primorava vrste.\nObjekti koji nisu [accent]null[] poređeni sa brojevima postaju 1, u suprotnom 0.
|
||||
lenum.notequal = Nejednakost. Primorava vrste.
|
||||
lenum.strictequal = Zacrtana jednakost. Ne primorava vrste.\nMože se koristiti radi provere [accent]null[]-a.
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Lagrade:
|
||||
sectors.resume = Återuppta
|
||||
sectors.launch = Skjuta upp
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = คลื่น:
|
||||
sectors.stored = คลังไอเท็ม:
|
||||
sectors.resume = ไปต่อ
|
||||
sectors.launch = ลงจอด
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = เลือก
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]ไม่มี (ดวงอาทิตย์)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID ของยูนิต/บล็อก/ไอเท็ม/ข
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = ไม่ทราบ
|
||||
lcategory.unknown.description = คำสั่งที่ไม่อยู่ในหมวดหมู่ใดๆเลย
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = เป็นจริงเสมอ
|
||||
lenum.idiv = หารจำนวนเต็ม
|
||||
lenum.div = หาร\nจะส่งกลับ[accent]ค่าว่าง[] หากหารศูนย์
|
||||
lenum.mod = โมดูโล่ (หารหาเศษ)
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = เท่ากับ แบบบังคับประเภท\nสิ่งที่ไม่ใช่ค่าว่างเมื่อเทียบกับตัวเลขจะส่งกลับค่า 1 นอกนั้นจะส่งกลับค่า 0
|
||||
lenum.notequal = ไม่เท่ากับ บังคับประเภท
|
||||
lenum.strictequal = เท่ากับที่เข้มงวด ไม่บังคับประเภท\nสามารถใช้ตรวจสอบหา[accent]ค่าว่าง[]ได้
|
||||
lenum.shl = เลื่อนบิตไปทางซ้าย
|
||||
lenum.shr = เลื่อนบิตไปทางขวา
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = หรือ แบบบิต
|
||||
lenum.land = และ เชิงตรรกะ
|
||||
lenum.and = และ แบบบิต
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Wave:
|
||||
sectors.stored = Stored:
|
||||
sectors.resume = Resume
|
||||
sectors.launch = Launch
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Select
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]none (sun)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Unknown
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Always true.
|
||||
lenum.idiv = Integer division.
|
||||
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
|
||||
lenum.mod = Modulo.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
|
||||
lenum.notequal = Not equal. Coerces types.
|
||||
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
|
||||
lenum.shl = Bit-shift left.
|
||||
lenum.shr = Bit-shift right.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Bitwise OR.
|
||||
lenum.land = Logical AND.
|
||||
lenum.and = Bitwise AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Dalga:
|
||||
sectors.stored = Depolanan:
|
||||
sectors.resume = Devam Et
|
||||
sectors.launch = Fırlat
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Seç
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]yok (güneş)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = Bir birim/blok/eşya/sıvı kimliği. \nBu arama operasyonun zıtt
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = ???
|
||||
lcategory.unknown.description = Kategorize edilmemiş talimatlar
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Her Zaman Doğru
|
||||
lenum.idiv = Tamsayı Bölme
|
||||
lenum.div = Bölme
|
||||
lenum.mod = Mod
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Eşit
|
||||
lenum.notequal = Eşit Değil
|
||||
lenum.strictequal = Aynı
|
||||
lenum.shl = Shift Sol
|
||||
lenum.shr = Shift Sağ
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Veya
|
||||
lenum.land = Çapraz Ve
|
||||
lenum.and = Ve
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Хвиля:
|
||||
sectors.stored = Зберігає:
|
||||
sectors.resume = Продовжити
|
||||
sectors.launch = Запустити
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Вибрати
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]нічого (сонце)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = Ідентифікатор одиниці/блоку/предмет
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Невідома категорія
|
||||
lcategory.unknown.description = Команди без категорії.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Завжди істинне.
|
||||
lenum.idiv = Ціле ділення.
|
||||
lenum.div = Ділення.\nПовертає [accent]null[] при діленні на нуль.
|
||||
lenum.mod = Залишок від ділення.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Рівно. Примусове приведення типів.\nНе-null об’єкти у порівнянні з числами стають 1, інакше — 0.
|
||||
lenum.notequal = Не рівно. Примусове приведення типів.
|
||||
lenum.strictequal = Сувора рівність. Примусового приведення типів немає.\nМожна використати для перевірки на [accent]null[].
|
||||
lenum.shl = Зсув бітів ліворуч.
|
||||
lenum.shr = Зсув бітів праворуч.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Побітове АБО (OR).
|
||||
lenum.land = Побітове логічне І.
|
||||
lenum.and = Побітове І.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = Đợt:
|
||||
sectors.stored = Lưu trữ:
|
||||
sectors.resume = Tiếp tục
|
||||
sectors.launch = Phóng
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = Chọn
|
||||
sectors.launchselect = Chọn đích phóng
|
||||
sectors.nonelaunch = [lightgray]không có (mặt trời)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = Định danh của một đơn vị/khối/vật phẩm/chất lỏ
|
||||
laccess.displaywidth = Độ rộng của một khối hiển thị tính bằng pixel.
|
||||
laccess.displayheight = Độ cao của một khối hiển thị tính bằng pixel.
|
||||
laccess.bufferusage = Số lệnh chưa xử lý trong bộ đệm đồ họa của một hiển thị.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = Không xác định
|
||||
lcategory.unknown.description = Chỉ lệnh không được phân loại.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = Luôn đúng.
|
||||
lenum.idiv = Chia lấy phần nguyên.
|
||||
lenum.div = Phép chia.\nTrả về [accent]rỗng (null)[] khi chia cho 0.
|
||||
lenum.mod = Chia lấy phần dư.
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = Bằng nhau. Ép kiểu.\nĐối tượng không-rỗng (non-null) so sánh với số sẽ thành 1, ngược lại là 0.
|
||||
lenum.notequal = Không bằng nhau. Ép kiểu.
|
||||
lenum.strictequal = Bằng nhau ràng buộc. Không ép kiểu.\nCó thể dùng để kiểm tra [accent]rỗng (null)[].
|
||||
lenum.shl = Nhảy bit sang trái.
|
||||
lenum.shr = Nhảy bit sang phải.
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = Phép toán bit OR.
|
||||
lenum.land = Phép toán logic AND.
|
||||
lenum.and = Phép toán bit AND.
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = 波次:
|
||||
sectors.stored = 贮存:
|
||||
sectors.resume = 继续
|
||||
sectors.launch = 发射
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = 选择
|
||||
sectors.launchselect = 选择发射目的地
|
||||
sectors.nonelaunch = [lightgray]无(自动销毁)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = 单位/块/物品/液体的 ID。\n这是 Lookup 的反向操作。
|
||||
laccess.displaywidth = 显示屏的宽度(以像素为单位)。
|
||||
laccess.displayheight = 显示屏的高度(以像素为单位)。
|
||||
laccess.bufferusage = 显示器图形缓冲区中未处理的命令数。
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = 未知
|
||||
lcategory.unknown.description = 未分类的指令
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = 无条件跳转
|
||||
lenum.idiv = 整数除法,返回不带小数的商
|
||||
lenum.div = 除法,除以 0 时返回 [accent]null[]
|
||||
lenum.mod = 求除法的余数
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = 相等。转换参数类型后进行比较\n与数字进行比较时,null 转换为 0 ,非 null 对象转换为 1
|
||||
lenum.notequal = 不相等。转换参数类型后进行比较
|
||||
lenum.strictequal = 严格相等。不转换参数类型\n可用于准确检查 [accent]null[] 对象
|
||||
lenum.shl = 左移位
|
||||
lenum.shr = 右移位
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = 按位或
|
||||
lenum.land = 逻辑与
|
||||
lenum.and = 按位与
|
||||
|
||||
@@ -793,6 +793,7 @@ sectors.wave = 波次:
|
||||
sectors.stored = 儲存:
|
||||
sectors.resume = 繼續
|
||||
sectors.launch = 發射
|
||||
sectors.viewsubmission = \ue80d View Submissions
|
||||
sectors.select = 選取
|
||||
sectors.launchselect = Select Launch Destination
|
||||
sectors.nonelaunch = [lightgray]無(太陽)
|
||||
@@ -2566,6 +2567,7 @@ laccess.id = ID of a unit/block/item/liquid.\nThis is the inverse of the lookup
|
||||
laccess.displaywidth = Width of a display block in pixels.
|
||||
laccess.displayheight = Height of a display block in pixels.
|
||||
laccess.bufferusage = Number of unprocessed commands in the graphics buffer of a display.
|
||||
laccess.operations = Number of operations performed on the block.\nFor displays, returns the number of drawflush operations.
|
||||
|
||||
lcategory.unknown = 未知
|
||||
lcategory.unknown.description = Uncategorized instructions.
|
||||
@@ -2599,11 +2601,13 @@ lenum.always = 永遠 true (直接跳).
|
||||
lenum.idiv = 整數除法,無條件捨去.
|
||||
lenum.div = 除法.\n除以零時回傳 [accent]null[]
|
||||
lenum.mod = Modulo,求餘數
|
||||
lenum.emod = True modulo, result is always positive.
|
||||
lenum.equal = 是否相等,不管資料型態。\n非null 物件和數值相比時回傳1
|
||||
lenum.notequal = 是否不相等,不管資料型態.
|
||||
lenum.strictequal = 嚴格檢查是否相等,會比照資料型態。\n可用來檢查[accent]null[]
|
||||
lenum.shl = 左移n位元
|
||||
lenum.shr = 右移n位元
|
||||
lenum.ushr = Unsigned bit-shift right.
|
||||
lenum.or = 位元 OR
|
||||
lenum.land = 邏輯 AND
|
||||
lenum.and = 位元 AND
|
||||
|
||||
@@ -181,4 +181,6 @@ IchMagSchokolade
|
||||
MonoChronos
|
||||
RushieWashie
|
||||
ITY
|
||||
Iniquit
|
||||
DSFdsfWxp
|
||||
Someone's Shadow
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
{presets:{windsweptIslands:97,stainedMountains:223,weatheredChannels:166,craters:219,extractionOutpost:213,coastline:164,navalFortress:165,frontier:86,groundZero:170,mycelialBastion:143,facility32m:65,atolls:75,overgrowth:142,testingGrounds:169,frozenForest:64,saltFlats:98,taintedWoods:145,infestedCanyons:85,desolateRift:271,nuclearComplex:228,ruinousShores:41,planetaryTerminal:217,impact0078:266,seaPort:214,geothermalStronghold:264,cruxscape:54,fungalPass:221,tarFields:99,biomassFacility:23},attackSectors:[0,2,5,6,10,11,12,13,16,19,24,25,27,28,30,33,36,47,48,49,51,57,59,60,66,67,68,70,71,76,78,82,90,104,106,110,114,115,121,127,128,129,133,138,148,149,154,158,172,180,182,200,202,204,210,224,225,233,234,235,241,243,248,254,255,257,259,265]}
|
||||
{presets:{windsweptIslands:97,stainedMountains:223,weatheredChannels:166,craters:219,extractionOutpost:213,coastline:164,navalFortress:165,frontier:86,groundZero:170,mycelialBastion:143,facility32m:65,atolls:75,overgrowth:142,testingGrounds:169,frozenForest:64,saltFlats:98,taintedWoods:145,infestedCanyons:85,desolateRift:271,nuclearComplex:228,ruinousShores:41,planetaryTerminal:217,impact0078:266,seaPort:214,geothermalStronghold:264,cruxscape:54,fungalPass:221,tarFields:99,biomassFacility:23},attackSectors:[0,6,13,16,19,20,24,27,30,47,55,66,67,69,76,92,94,103,111,116,127,133,138,150,157,161,162,176,180,185,191,192,197,200,204,207,225,230,237,242,243,244,245,246,247,248,251,254,259,263,265]}
|
||||
@@ -1,6 +1,7 @@
|
||||
attribute vec4 a_position;
|
||||
attribute vec3 a_normal;
|
||||
attribute vec4 a_color;
|
||||
attribute vec4 a_emissive;
|
||||
|
||||
uniform mat4 u_proj;
|
||||
uniform mat4 u_trans;
|
||||
@@ -8,6 +9,7 @@ uniform vec3 u_lightdir;
|
||||
uniform vec3 u_camdir;
|
||||
uniform vec3 u_campos;
|
||||
uniform vec3 u_ambientColor;
|
||||
uniform float u_emissive;
|
||||
|
||||
varying vec4 v_col;
|
||||
|
||||
@@ -19,13 +21,18 @@ void main(){
|
||||
//TODO this calculation is probably wrong
|
||||
vec3 lightReflect = normalize(reflect(a_normal, u_lightdir));
|
||||
vec3 vertexEye = normalize(u_campos - (u_trans * a_position).xyz);
|
||||
|
||||
float albedo = 1.0 - a_color.a;
|
||||
|
||||
float specularFactor = dot(vertexEye, lightReflect);
|
||||
if(specularFactor > 0.0){
|
||||
specular = vec3(1.0 * pow(specularFactor, 40.0)) * (1.0-a_color.a);
|
||||
specular = vec3(1.0 * pow(specularFactor, 40.0)) * albedo;
|
||||
}
|
||||
|
||||
vec3 norc = (u_ambientColor + specular) * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
|
||||
|
||||
v_col = vec4(a_color.rgb, 1.0) * vec4(norc, 1.0);
|
||||
float emissive = a_emissive.a * u_emissive * min(pow(max(0.0, (1.0 - norc.r) * 1.2), 3.0), 1.1);
|
||||
|
||||
v_col = vec4(mix(a_color.rgb, a_emissive.rgb, emissive), 1.0) * vec4(mix(norc, vec3(1.0), emissive), 1.0);
|
||||
gl_Position = u_proj * u_trans * a_position;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ public class Vars implements Loadable{
|
||||
public static final int minModGameVersion = 136;
|
||||
/** Min game version for java mods specifically - this is higher, as Java mods have more breaking changes. */
|
||||
public static final int minJavaModGameVersion = 147;
|
||||
/** If true, a button to view sector submission threads is shown. */
|
||||
public static boolean showSectorSubmissions = true;
|
||||
/** If true, the BE server list is always used. */
|
||||
public static boolean forceBeServers = false;
|
||||
/** If true, mod code and scripts do not run. For internal testing only. This WILL break mods if enabled. */
|
||||
|
||||
@@ -540,7 +540,7 @@ public class Pathfinder implements Runnable{
|
||||
if(!targets.isEmpty()){
|
||||
boolean any = false;
|
||||
for(Building other : targets){
|
||||
if((other.items != null && other.items.any()) || other.status() != BlockStatus.noInput){
|
||||
if(((other.items != null && other.items.any()) || other.status() != BlockStatus.noInput) && other.block.targetable){
|
||||
out.add(other.tile.array());
|
||||
any = true;
|
||||
}
|
||||
|
||||
@@ -141,6 +141,8 @@ public class RtsAI{
|
||||
boolean handleSquad(Seq<Unit> units, boolean noDefenders){
|
||||
if(units.isEmpty()) return false;
|
||||
|
||||
boolean naval = units.first() instanceof WaterMovec;
|
||||
|
||||
float health = 0f, dps = 0f;
|
||||
float ax = 0f, ay = 0f;
|
||||
boolean targetAir = true, targetGround = true;
|
||||
@@ -165,7 +167,7 @@ public class RtsAI{
|
||||
boolean defendingCore = false;
|
||||
|
||||
//there is something to defend, see if it's worth the time
|
||||
if(damaged.size > 0){
|
||||
if(damaged.size > 0 && !naval){
|
||||
//TODO do the weights matter at all?
|
||||
//for(var build : damaged){
|
||||
//float w = estimateStats(ax, ay, dps, health);
|
||||
@@ -251,7 +253,7 @@ public class RtsAI{
|
||||
}
|
||||
}
|
||||
|
||||
var build = anyDefend ? null : findTarget(ax, ay, units.size, dps, health, units.first().flag == 0, units.first().isFlying());
|
||||
var build = anyDefend ? null : findTarget(ax, ay, units.size, dps, health, units.first().flag == 0, units.first().isFlying(), naval);
|
||||
|
||||
if(build != null || anyDefend){
|
||||
for(var unit : units){
|
||||
@@ -274,7 +276,7 @@ public class RtsAI{
|
||||
return anyDefend;
|
||||
}
|
||||
|
||||
@Nullable Building findTarget(float x, float y, int total, float dps, float health, boolean checkWeight, boolean air){
|
||||
@Nullable Building findTarget(float x, float y, int total, float dps, float health, boolean checkWeight, boolean air, boolean naval){
|
||||
if(total < data.team.rules().rtsMinSquad) return null;
|
||||
|
||||
//flag priority?
|
||||
@@ -282,8 +284,13 @@ public class RtsAI{
|
||||
//2. factory
|
||||
//3. core
|
||||
targets.clear();
|
||||
for(var flag : flags){
|
||||
targets.addAll(Vars.indexer.getEnemy(data.team, flag));
|
||||
if(naval){
|
||||
//naval units can only target enemy cores, because those are assumed to always be reachable. other blocks may not be!
|
||||
targets.addAll(Vars.indexer.getEnemy(data.team, BlockFlag.core));
|
||||
}else{
|
||||
for(var flag : flags){
|
||||
targets.addAll(Vars.indexer.getEnemy(data.team, flag));
|
||||
}
|
||||
}
|
||||
targets.removeAll(b -> assignedTargets.contains(b.id) || invalidTarget.contains(b.pos()));
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ public class UnitGroup{
|
||||
}
|
||||
|
||||
private void updateRaycast(int index, Vec2 dest, Vec2 v1){
|
||||
if(collisionLayer != PhysicsProcess.layerFlying){
|
||||
if(collisionLayer != PhysicsProcess.layerFlying && originalPositions != null && positions != null){
|
||||
|
||||
//coordinates in world space
|
||||
float
|
||||
|
||||
@@ -41,7 +41,7 @@ public class FlyingAI extends AIController{
|
||||
Building closest = null;
|
||||
float cdist = 0f;
|
||||
for(Building t : list){
|
||||
if((t.items != null && t.items.any()) || t.status() != BlockStatus.noInput){
|
||||
if(((t.items != null && t.items.any()) || t.status() != BlockStatus.noInput) && t.block.targetable){
|
||||
float dst = t.dst2(x, y);
|
||||
if(closest == null || dst < cdist){
|
||||
closest = t;
|
||||
|
||||
@@ -3437,7 +3437,6 @@ public class Blocks{
|
||||
hitEffect = Fx.hitLancer;
|
||||
despawnEffect = Fx.none;
|
||||
status = StatusEffects.shocked;
|
||||
statusDuration = 10f;
|
||||
hittable = false;
|
||||
lightColor = Color.white;
|
||||
collidesAir = false;
|
||||
@@ -3489,7 +3488,6 @@ public class Blocks{
|
||||
despawnEffect = Fx.blastExplosion;
|
||||
|
||||
status = StatusEffects.blasted;
|
||||
statusDuration = 60f;
|
||||
|
||||
hitColor = backColor = trailColor = Pal.blastAmmoBack;
|
||||
frontColor = Pal.blastAmmoFront;
|
||||
@@ -3915,7 +3913,6 @@ public class Blocks{
|
||||
collidesGround = true;
|
||||
|
||||
status = StatusEffects.blasted;
|
||||
statusDuration = 60f;
|
||||
|
||||
backColor = hitColor = trailColor = Pal.blastAmmoBack;
|
||||
frontColor = Pal.blastAmmoFront;
|
||||
@@ -4385,6 +4382,7 @@ public class Blocks{
|
||||
targetInterval = 5f;
|
||||
newTargetInterval = 30f;
|
||||
targetUnderBlocks = false;
|
||||
shootY = 8f;
|
||||
|
||||
float r = range = 130f;
|
||||
|
||||
@@ -4421,7 +4419,6 @@ public class Blocks{
|
||||
);
|
||||
|
||||
scaledHealth = 210;
|
||||
shootY = 7f;
|
||||
size = 3;
|
||||
|
||||
researchCost = with(Items.tungsten, 400, Items.silicon, 400, Items.oxide, 80, Items.beryllium, 800);
|
||||
@@ -5455,7 +5452,6 @@ public class Blocks{
|
||||
hitEffect = Fx.hitLancer;
|
||||
despawnEffect = Fx.none;
|
||||
status = StatusEffects.shocked;
|
||||
statusDuration = 10f;
|
||||
hittable = false;
|
||||
lightColor = Color.white;
|
||||
buildingDamageMultiplier = 0.25f;
|
||||
|
||||
@@ -111,7 +111,7 @@ public class SectorPresets{
|
||||
}};
|
||||
|
||||
fungalPass = new SectorPreset("fungalPass", serpulo, 21){{
|
||||
difficulty = 4;
|
||||
difficulty = 2;
|
||||
}};
|
||||
|
||||
infestedCanyons = new SectorPreset("infestedCanyons", serpulo, 210){{
|
||||
|
||||
@@ -3829,8 +3829,10 @@ public class UnitTypes{
|
||||
|
||||
engineSize = 4.8f;
|
||||
engineOffset = 61 / 4f;
|
||||
range = 4.3f * 60f * 1.4f;
|
||||
|
||||
abilities.add(new SuppressionFieldAbility(){{
|
||||
reload = 60f * 8f;
|
||||
orbRadius = 5.3f;
|
||||
y = 1f;
|
||||
}});
|
||||
@@ -3846,36 +3848,59 @@ public class UnitTypes{
|
||||
recoil = 1f;
|
||||
rotationLimit = 60f;
|
||||
|
||||
bullet = new BulletType(){{
|
||||
bullet = new BasicBulletType(4.3f, 70f, "missile-large"){{
|
||||
shootEffect = Fx.shootBig;
|
||||
smokeEffect = Fx.shootBigSmoke2;
|
||||
shake = 1f;
|
||||
speed = 0f;
|
||||
lifetime = 60 * 0.496f;
|
||||
rangeOverride = 361.2f;
|
||||
followAimSpeed = 5f;
|
||||
|
||||
width = 12f;
|
||||
height = 22f;
|
||||
hitSize = 7f;
|
||||
hitColor = backColor = trailColor = Pal.sapBulletBack;
|
||||
trailWidth = 3f;
|
||||
trailLength = 12;
|
||||
hitEffect = despawnEffect = Fx.hitBulletColor;
|
||||
|
||||
keepVelocity = false;
|
||||
collidesGround = true;
|
||||
collidesAir = false;
|
||||
|
||||
spawnUnit = new MissileUnitType("quell-missile"){{
|
||||
targetAir = false;
|
||||
speed = 4.3f;
|
||||
maxRange = 6f;
|
||||
lifetime = 60f * 1.4f;
|
||||
outlineColor = Pal.darkOutline;
|
||||
engineColor = trailColor = Pal.sapBulletBack;
|
||||
engineLayer = Layer.effect;
|
||||
health = 45;
|
||||
loopSoundVolume = 0.1f;
|
||||
//workaround to get the missile to behave like in spawnUnit while still spawning on death
|
||||
fragRandomSpread = 0;
|
||||
fragBullets = 1;
|
||||
fragVelocityMin = 1f;
|
||||
fragOffsetMax = 1f;
|
||||
|
||||
weapons.add(new Weapon(){{
|
||||
shootSound = Sounds.none;
|
||||
shootCone = 360f;
|
||||
mirror = false;
|
||||
reload = 1f;
|
||||
shootOnDeath = true;
|
||||
bullet = new ExplosionBulletType(110f, 25f){{
|
||||
shootEffect = Fx.massiveExplosion;
|
||||
collidesAir = false;
|
||||
}};
|
||||
}});
|
||||
fragBullet = new BulletType(){{
|
||||
speed = 0f;
|
||||
keepVelocity = false;
|
||||
collidesAir = false;
|
||||
spawnUnit = new MissileUnitType("quell-missile"){{
|
||||
targetAir = false;
|
||||
speed = 4.3f;
|
||||
maxRange = 6f;
|
||||
lifetime = 60f * (1.4f - 0.496f);
|
||||
outlineColor = Pal.darkOutline;
|
||||
engineColor = trailColor = Pal.sapBulletBack;
|
||||
engineLayer = Layer.effect;
|
||||
health = 45;
|
||||
loopSoundVolume = 0.1f;
|
||||
|
||||
weapons.add(new Weapon() {{
|
||||
shootSound = Sounds.none;
|
||||
shootCone = 360f;
|
||||
mirror = false;
|
||||
reload = 1f;
|
||||
shootOnDeath = true;
|
||||
bullet = new ExplosionBulletType(110f, 25f) {{
|
||||
shootEffect = Fx.massiveExplosion;
|
||||
collidesAir = false;
|
||||
}};
|
||||
}});
|
||||
}};
|
||||
}};
|
||||
}};
|
||||
}});
|
||||
@@ -3909,6 +3934,8 @@ public class UnitTypes{
|
||||
int parts = 10;
|
||||
|
||||
abilities.add(new SuppressionFieldAbility(){{
|
||||
reload = 60 * 15f;
|
||||
range = 320f;
|
||||
orbRadius = orbRad;
|
||||
particleSize = partRad;
|
||||
y = 10f;
|
||||
|
||||
@@ -156,6 +156,16 @@ public class Logic implements ApplicationListener{
|
||||
if(!net.client() && e.sector == state.getSector() && e.sector.isBeingPlayed()){
|
||||
state.rules.waveTeam.data().destroyToDerelict();
|
||||
}
|
||||
|
||||
if(!net.client() && e.sector.planet.generator != null){
|
||||
e.sector.planet.generator.onSectorCaptured(e.sector);
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(SectorLoseEvent.class, e -> {
|
||||
if(!net.client() && e.sector.planet.generator != null){
|
||||
e.sector.planet.generator.onSectorLost(e.sector);
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(BlockDestroyEvent.class, e -> {
|
||||
@@ -462,7 +472,7 @@ public class Logic implements ApplicationListener{
|
||||
if(rules.fillItems && data.cores.size > 0){
|
||||
var core = data.cores.first();
|
||||
content.items().each(i -> {
|
||||
if(i.isOnPlanet(Vars.state.getPlanet())){
|
||||
if(i.isOnPlanet(Vars.state.getPlanet()) && !i.isHidden()){
|
||||
core.items.set(i, core.getMaximumAccepted(i));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -64,6 +64,9 @@ public class DrawOperation{
|
||||
|
||||
Block block = content.block(to);
|
||||
tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation);
|
||||
if(tile.build != null){
|
||||
tile.build.enabled = true;
|
||||
}
|
||||
|
||||
tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y));
|
||||
}else if(type == OpType.rotation.ordinal()){
|
||||
|
||||
@@ -222,38 +222,38 @@ public class Damage{
|
||||
public static float collideLaser(Bullet b, float length, boolean large, boolean laser, int pierceCap){
|
||||
float resultLength = findPierceLength(b, pierceCap, laser, length);
|
||||
|
||||
collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), resultLength, large, laser, pierceCap);
|
||||
collideLine(b, b.team, b.x, b.y, b.rotation(), resultLength, large, laser, pierceCap);
|
||||
|
||||
b.fdata = resultLength;
|
||||
|
||||
return resultLength;
|
||||
}
|
||||
|
||||
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length){
|
||||
collideLine(hitter, team, effect, x, y, angle, length, false);
|
||||
public static void collideLine(Bullet hitter, Team team, float x, float y, float angle, float length){
|
||||
collideLine(hitter, team, x, y, angle, length, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Damages entities in a line.
|
||||
* Only enemies of the specified team are damaged.
|
||||
*/
|
||||
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){
|
||||
collideLine(hitter, team, effect, x, y, angle, length, large, true);
|
||||
public static void collideLine(Bullet hitter, Team team, float x, float y, float angle, float length, boolean large){
|
||||
collideLine(hitter, team, x, y, angle, length, large, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Damages entities in a line.
|
||||
* Only enemies of the specified team are damaged.
|
||||
*/
|
||||
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large, boolean laser){
|
||||
collideLine(hitter, team, effect, x, y, angle, length, large, laser, -1);
|
||||
public static void collideLine(Bullet hitter, Team team, float x, float y, float angle, float length, boolean large, boolean laser){
|
||||
collideLine(hitter, team, x, y, angle, length, large, laser, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Damages entities in a line.
|
||||
* Only enemies of the specified team are damaged.
|
||||
*/
|
||||
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large, boolean laser, int pierceCap){
|
||||
public static void collideLine(Bullet hitter, Team team, float x, float y, float angle, float length, boolean large, boolean laser, int pierceCap){
|
||||
length = findLength(hitter, length, laser, pierceCap);
|
||||
hitter.fdata = length;
|
||||
|
||||
@@ -545,8 +545,10 @@ public class Damage{
|
||||
tileDamage(team, x, y, baseRadius, damage, null);
|
||||
}
|
||||
|
||||
public static void tileDamage(Team team, int x, int y, float baseRadius, float damage, @Nullable Bullet source){
|
||||
public static void tileDamage(Team team, int tx, int ty, float baseRadius, float damage, @Nullable Bullet source){
|
||||
Time.run(0f, () -> {
|
||||
int x = Mathf.clamp(tx, -100, world.width() + 100), y = Mathf.clamp(ty, -100, world.height() + 100);
|
||||
|
||||
var in = world.build(x, y);
|
||||
//spawned inside a multiblock. this means that damage needs to be dealt directly.
|
||||
//why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion.
|
||||
|
||||
@@ -17,6 +17,7 @@ public class SuppressionFieldAbility extends Ability{
|
||||
protected static Rand rand = new Rand();
|
||||
|
||||
public float reload = 60f * 1.5f;
|
||||
public float maxDelay = 60f * 1.5f;
|
||||
public float range = 200f;
|
||||
|
||||
public float orbRadius = 4.1f, orbMidScl = 0.33f, orbSinScl = 8f, orbSinMag = 1f;
|
||||
@@ -55,9 +56,9 @@ public class SuppressionFieldAbility extends Ability{
|
||||
public void update(Unit unit){
|
||||
if(!active) return;
|
||||
|
||||
if((timer += Time.delta) >= reload){
|
||||
if((timer += Time.delta) >= maxDelay){
|
||||
Tmp.v1.set(x, y).rotate(unit.rotation - 90f).add(unit);
|
||||
Damage.applySuppression(unit.team, Tmp.v1.x, Tmp.v1.y, range, reload, reload, applyParticleChance, unit, effectColor);
|
||||
Damage.applySuppression(unit.team, Tmp.v1.x, Tmp.v1.y, range, reload, maxDelay, applyParticleChance, unit, effectColor);
|
||||
timer = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class ContinuousBulletType extends BulletType{
|
||||
if(timescaleDamage && b.owner instanceof Building build){
|
||||
b.damage *= build.timeScale();
|
||||
}
|
||||
Damage.collideLine(b, b.team, hitEffect, b.x, b.y, b.rotation(), currentLength(b), largeHit, laserAbsorb, pierceCap);
|
||||
Damage.collideLine(b, b.team, b.x, b.y, b.rotation(), currentLength(b), largeHit, laserAbsorb, pierceCap);
|
||||
b.damage = damage;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,13 +55,13 @@ public class ContinuousLaserBulletType extends ContinuousBulletType{
|
||||
float ellipseLenScl = Mathf.lerp(1 - i / (float)(colors.length), 1f, pointyScaling);
|
||||
|
||||
Lines.stroke(stroke);
|
||||
Lines.lineAngle(b.x, b.y, rot, realLength - frontLength, false);
|
||||
Lines.lineAngle(b.x, b.y, rot, Math.max(0, realLength - frontLength), false);
|
||||
|
||||
//back ellipse
|
||||
Drawf.flameFront(b.x, b.y, divisions, rot + 180f, backLength, stroke / 2f);
|
||||
|
||||
//front ellipse
|
||||
Tmp.v1.trnsExact(rot, realLength - frontLength);
|
||||
Tmp.v1.trnsExact(rot, Math.max(0, realLength - frontLength));
|
||||
Drawf.flameFront(b.x + Tmp.v1.x, b.y + Tmp.v1.y, divisions, rot, frontLength * ellipseLenScl, stroke / 2f);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@ import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.blocks.distribution.MassDriver.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
@@ -89,5 +91,17 @@ public class MassDriverBolt extends BasicBulletType{
|
||||
public void hit(Bullet b, float hitx, float hity){
|
||||
super.hit(b, hitx, hity);
|
||||
despawned(b);
|
||||
if(b.data() instanceof DriverBulletData data){
|
||||
float explosiveness = 0f;
|
||||
float flammability = 0f;
|
||||
float power = 0f;
|
||||
for(int i = 0; i < data.items.length; i++){
|
||||
Item item = content.item(i);
|
||||
explosiveness += item.explosiveness * data.items[i];
|
||||
flammability += item.flammability * data.items[i];
|
||||
power += item.charge * Mathf.pow(data.items[i], 1.1f) * 25f;
|
||||
}
|
||||
Damage.dynamicExplosion(b.x, b.y, flammability / 10f, explosiveness / 10f, power, 1f, state.rules.damageExplosions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class RailBulletType extends BulletType{
|
||||
super.init(b);
|
||||
|
||||
b.fdata = length;
|
||||
Damage.collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), length, false, false, pierceCap);
|
||||
Damage.collideLine(b, b.team, b.x, b.y, b.rotation(), length, false, false, pierceCap);
|
||||
float resultLen = b.fdata;
|
||||
|
||||
Vec2 nor = Tmp.v1.trns(b.rotation(), 1f).nor();
|
||||
|
||||
@@ -35,7 +35,7 @@ import static mindustry.logic.GlobalVars.*;
|
||||
@Component(base = true)
|
||||
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Syncc, Shieldc, Displayable, Ranged, Minerc, Builderc, Senseable, Settable{
|
||||
private static final Vec2 tmp1 = new Vec2(), tmp2 = new Vec2();
|
||||
static final float warpDst = 20f;
|
||||
static final float warpDst = 8f;
|
||||
|
||||
@Import boolean dead, disarmed;
|
||||
@Import float x, y, rotation, maxHealth, drag, armor, hitSize, health, shield, ammo, dragMultiplier, armorOverride, speedMultiplier;
|
||||
@@ -643,11 +643,11 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
//repel unit out of bounds
|
||||
if(x < left) dx += (-(x - left)/warpDst);
|
||||
if(y < bot) dy += (-(y - bot)/warpDst);
|
||||
if(x > right) dx -= (x - right)/warpDst;
|
||||
if(y > top) dy -= (y - top)/warpDst;
|
||||
if(x > right - tilesize) dx -= (x - (right - tilesize))/warpDst;
|
||||
if(y > top - tilesize) dy -= (y - (top - tilesize))/warpDst;
|
||||
|
||||
velAddNet(dx * Time.delta, dy * Time.delta);
|
||||
float margin = tilesize * 2f;
|
||||
float margin = tilesize * 1f;
|
||||
x = Mathf.clamp(x, left - margin, right - tilesize + margin);
|
||||
y = Mathf.clamp(y, bot - margin, top - tilesize + margin);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ public class BuildPlan implements Position, QuadTreeObject{
|
||||
public boolean breaking;
|
||||
/** Config int. Not used unless hasConfig is true.*/
|
||||
public Object config;
|
||||
/** Original position, only used in schematics.*/
|
||||
public int originalX, originalY, originalWidth, originalHeight;
|
||||
|
||||
/** Last progress.*/
|
||||
public float progress;
|
||||
@@ -65,6 +63,7 @@ public class BuildPlan implements Position, QuadTreeObject{
|
||||
public BuildPlan(){
|
||||
|
||||
}
|
||||
|
||||
public boolean placeable(Team team){
|
||||
return Build.validPlace(block, team, x, y, rotation);
|
||||
}
|
||||
@@ -111,22 +110,12 @@ public class BuildPlan implements Position, QuadTreeObject{
|
||||
copy.block = block;
|
||||
copy.breaking = breaking;
|
||||
copy.config = config;
|
||||
copy.originalX = originalX;
|
||||
copy.originalY = originalY;
|
||||
copy.progress = progress;
|
||||
copy.initialized = initialized;
|
||||
copy.animScale = animScale;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public BuildPlan original(int x, int y, int originalWidth, int originalHeight){
|
||||
originalX = x;
|
||||
originalY = y;
|
||||
this.originalWidth = originalWidth;
|
||||
this.originalHeight = originalHeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Rect bounds(Rect rect){
|
||||
if(breaking){
|
||||
return rect.set(-100f, -100f, 0f, 0f);
|
||||
|
||||
@@ -119,8 +119,7 @@ public final class FogControl implements CustomChunk{
|
||||
|
||||
var data = data(team);
|
||||
if(data == null) return false;
|
||||
if(x < 0 || y < 0 || x >= ww || y >= wh) return false;
|
||||
return data.read.get(x + y * ww);
|
||||
return data.read.get(Mathf.clamp(x, 0, ww - 1) + Mathf.clamp(y, 0, wh - 1) * ww);
|
||||
}
|
||||
|
||||
public void resetFog(){
|
||||
|
||||
@@ -3,6 +3,7 @@ package mindustry.game;
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.Texture.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
@@ -98,7 +99,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerLegacyMarker(String name, Prov<? extends ObjectiveMarker> prov) {
|
||||
public static void registerLegacyMarker(String name, Prov<? extends ObjectiveMarker> prov){
|
||||
Class<?> type = prov.get().getClass();
|
||||
|
||||
markerNameToType.put(name, prov);
|
||||
@@ -663,7 +664,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
}
|
||||
}
|
||||
|
||||
/** Marker used for drawing various content to indicate something along with an objective. Mostly used as UI overlay. */
|
||||
/** Marker used for drawing various content to indicate something along with an objective. Mostly used as UI overlay. */
|
||||
public static abstract class ObjectiveMarker{
|
||||
/** Internal use only! Do not access. */
|
||||
public transient int arrayIndex;
|
||||
@@ -714,7 +715,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
state.mapLocales.getProperty(key + ".mobile") :
|
||||
state.mapLocales.containsProperty(key) ?
|
||||
state.mapLocales.getProperty(key) :
|
||||
Core.bundle.get(key);
|
||||
Core.bundle.get(key + ".mobile", Core.bundle.get(key));
|
||||
}else{
|
||||
out =
|
||||
state.mapLocales.containsProperty(key) ?
|
||||
@@ -822,13 +823,8 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
switch(type){
|
||||
case fontSize -> fontSize = (float)p1;
|
||||
case textHeight -> textHeight = (float)p1;
|
||||
case labelFlags -> {
|
||||
if(!Mathf.equal((float)p1, 0f)){
|
||||
flags |= WorldLabel.flagBackground;
|
||||
}else{
|
||||
flags &= ~WorldLabel.flagBackground;
|
||||
}
|
||||
}
|
||||
case outline -> flags = (byte)Pack.bitmask(flags, WorldLabel.flagOutline, !Mathf.equal((float)p1, 0f));
|
||||
case labelFlags -> flags = (byte)Pack.bitmask(flags, WorldLabel.flagBackground, !Mathf.equal((float)p1, 0f));
|
||||
case radius -> radius = (float)p1;
|
||||
case rotation -> rotation = (float)p1;
|
||||
case color -> color.fromDouble(p1);
|
||||
@@ -838,13 +834,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
|
||||
if(!Double.isNaN(p2)){
|
||||
switch(type){
|
||||
case labelFlags -> {
|
||||
if(!Mathf.equal((float)p2, 0f)){
|
||||
flags |= WorldLabel.flagOutline;
|
||||
}else{
|
||||
flags &= ~WorldLabel.flagOutline;
|
||||
}
|
||||
}
|
||||
case labelFlags -> flags = (byte)Pack.bitmask(flags, WorldLabel.flagOutline, !Mathf.equal((float)p2, 0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -944,7 +934,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
Lines.poly(pos.x, pos.y, sides, (radius + 1f) * scaleFactor, rotation + startAngle, rotation + endAngle);
|
||||
}else{
|
||||
Draw.color(color);
|
||||
if (startAngle < endAngle){
|
||||
if(startAngle < endAngle){
|
||||
Fill.arc(pos.x, pos.y, radius * scaleFactor, (endAngle - startAngle) / 360f, rotation + startAngle, sides);
|
||||
}else{
|
||||
Fill.arc(pos.x, pos.y, radius * scaleFactor, (startAngle - endAngle) / 360f, rotation + endAngle, sides);
|
||||
@@ -962,6 +952,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
switch(type){
|
||||
case radius -> radius = (float)p1;
|
||||
case stroke -> stroke = (float)p1;
|
||||
case outline -> outline = !Mathf.equal((float)p1, 0f);
|
||||
case rotation -> rotation = (float)p1;
|
||||
case color -> color.fromDouble(p1);
|
||||
case shape -> sides = (int)p1;
|
||||
@@ -1025,25 +1016,14 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
if(!Double.isNaN(p1)){
|
||||
switch(type){
|
||||
case fontSize -> fontSize = (float)p1;
|
||||
case labelFlags -> {
|
||||
if(!Mathf.equal((float)p1, 0f)){
|
||||
flags |= WorldLabel.flagBackground;
|
||||
}else{
|
||||
flags &= ~WorldLabel.flagBackground;
|
||||
}
|
||||
}
|
||||
case outline -> flags = (byte)Pack.bitmask(flags, WorldLabel.flagOutline, !Mathf.equal((float)p1, 0f));
|
||||
case labelFlags -> flags = (byte)Pack.bitmask(flags, WorldLabel.flagBackground, !Mathf.equal((float)p1, 0f));
|
||||
}
|
||||
}
|
||||
|
||||
if(!Double.isNaN(p2)){
|
||||
switch(type){
|
||||
case labelFlags -> {
|
||||
if(!Mathf.equal((float)p2, 0f)){
|
||||
flags |= WorldLabel.flagOutline;
|
||||
}else{
|
||||
flags &= ~WorldLabel.flagOutline;
|
||||
}
|
||||
}
|
||||
case labelFlags -> flags = (byte)Pack.bitmask(flags, WorldLabel.flagOutline, !Mathf.equal((float)p2, 0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1101,6 +1081,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
case endPos -> endPos.x = (float)p1 * tilesize;
|
||||
case stroke -> stroke = (float)p1;
|
||||
case color -> color1.set(color2.fromDouble(p1));
|
||||
case outline -> outline = !Mathf.equal((float)p1, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,7 +1092,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
}
|
||||
|
||||
if(!Double.isNaN(p1) && !Double.isNaN(p2)){
|
||||
switch (type){
|
||||
switch(type){
|
||||
case posi -> ((int)p1 == 0 ? pos : (int)p1 == 1 ? endPos : Tmp.v1).x = (float)p2 * tilesize;
|
||||
case colori -> ((int)p1 == 0 ? color1 : (int)p1 == 1 ? color2 : Tmp.c1).fromDouble(p2);
|
||||
}
|
||||
@@ -1199,7 +1180,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
|
||||
private transient TextureRegion fetchedRegion;
|
||||
|
||||
public QuadMarker() {
|
||||
public QuadMarker(){
|
||||
for(int i = 0; i < 4; i++){
|
||||
vertices[i * 6 + 2] = Color.white.toFloatBits();
|
||||
vertices[i * 6 + 5] = Color.clearFloatBits;
|
||||
@@ -1250,7 +1231,7 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
|
||||
boolean firstUpdate = fetchedRegion == null;
|
||||
|
||||
if(fetchedRegion == null) fetchedRegion = new TextureRegion();
|
||||
if(firstUpdate) fetchedRegion = new TextureRegion();
|
||||
Tmp.tr1.set(fetchedRegion);
|
||||
|
||||
lookupRegion(textureName, fetchedRegion);
|
||||
@@ -1258,21 +1239,22 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
if(firstUpdate){
|
||||
if(mapRegion){
|
||||
mapRegion = false;
|
||||
|
||||
// possibly from the editor, we need to clamp the values
|
||||
for(int i = 0; i < 4; i++){
|
||||
vertices[i * 6 + 3] = Mathf.map(Mathf.clamp(vertices[i * 6 + 3]), fetchedRegion.u, fetchedRegion.u2);
|
||||
vertices[i * 6 + 4] = Mathf.map(1 - Mathf.clamp(vertices[i * 6 + 4]), fetchedRegion.v, fetchedRegion.v2);
|
||||
setUv(i, vertices[i * 6 + 3], vertices[i * 6 + 4]);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for(int i = 0; i < 4; i++){
|
||||
vertices[i * 6 + 3] = Mathf.map(vertices[i * 6 + 3], Tmp.tr1.u, Tmp.tr1.u2, fetchedRegion.u, fetchedRegion.u2);
|
||||
vertices[i * 6 + 4] = Mathf.map(vertices[i * 6 + 4], Tmp.tr1.v, Tmp.tr1.v2, fetchedRegion.v, fetchedRegion.v2);
|
||||
setUv(i, unmap(vertices[i * 6 + 3], Tmp.tr1.u, Tmp.tr1.u2), 1 - unmap(vertices[i * 6 + 4], Tmp.tr1.v, Tmp.tr1.v2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static float unmap(float x, float from, float to){
|
||||
if(Mathf.equal(from, to)) return x;
|
||||
return (x - from) / (to - from);
|
||||
}
|
||||
|
||||
private void setPos(int i, double x, double y){
|
||||
if(i >= 0 && i < 4){
|
||||
if(!Double.isNaN(x)) vertices[i * 6] = (float)x * tilesize;
|
||||
@@ -1290,11 +1272,16 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
|
||||
if(i >= 0 && i < 4){
|
||||
if(fetchedRegion == null) setTexture(textureName);
|
||||
|
||||
if(!Double.isNaN(u)) vertices[i * 6 + 3] = Mathf.map(Mathf.clamp((float)u), fetchedRegion.u, fetchedRegion.u2);
|
||||
if(!Double.isNaN(v)) vertices[i * 6 + 4] = Mathf.map(1 - Mathf.clamp((float)v), fetchedRegion.v, fetchedRegion.v2);
|
||||
if(!Double.isNaN(u)){
|
||||
boolean clampU = fetchedRegion.texture.getUWrap() != TextureWrap.mirroredRepeat && fetchedRegion.texture.getUWrap() != TextureWrap.repeat;
|
||||
vertices[i * 6 + 3] = Mathf.map(clampU ? Mathf.clamp((float)u) : (float)u, fetchedRegion.u, fetchedRegion.u2);
|
||||
}
|
||||
if(!Double.isNaN(v)){
|
||||
boolean clampV = fetchedRegion.texture.getVWrap() != TextureWrap.mirroredRepeat && fetchedRegion.texture.getVWrap() != TextureWrap.repeat;
|
||||
vertices[i * 6 + 4] = Mathf.map(clampV ? 1 - Mathf.clamp((float)v) : 1 - (float)v, fetchedRegion.v, fetchedRegion.v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void lookupRegion(String name, TextureRegion out){
|
||||
|
||||
@@ -72,7 +72,32 @@ public class Saves{
|
||||
|
||||
lastSectorSave = saves.find(s -> s.isSector() && s.getName().equals(Core.settings.getString("last-sector-save", "<none>")));
|
||||
|
||||
ObjectSet<Sector> infoToClear = new ObjectSet<>(), remapped = new ObjectSet<>();
|
||||
class Remap{
|
||||
//file in the temp folder
|
||||
Fi sourceFile;
|
||||
//slot of source sector to move file for
|
||||
SaveSlot slot;
|
||||
Sector sourceSector;
|
||||
//sector info from source sector to move into
|
||||
SectorInfo sourceInfo;
|
||||
|
||||
//file to copy to
|
||||
Fi destFile;
|
||||
//destination sector to move to
|
||||
Sector destSector;
|
||||
|
||||
Remap(SaveSlot slot, Fi sourceFile, Sector sourceSector, SectorInfo sourceInfo, Fi destFile, Sector destSector){
|
||||
this.slot = slot;
|
||||
this.sourceFile = sourceFile;
|
||||
this.sourceSector = sourceSector;
|
||||
this.sourceInfo = sourceInfo;
|
||||
this.destFile = destFile;
|
||||
this.destSector = destSector;
|
||||
}
|
||||
}
|
||||
|
||||
Seq<Remap> remaps = new Seq<>();
|
||||
ObjectSet<Sector> remapped = new ObjectSet<>();
|
||||
|
||||
//automatically assign sector save slots
|
||||
for(SaveSlot slot : saves){
|
||||
@@ -102,22 +127,13 @@ public class Saves{
|
||||
if(!slot.file.equals(getSectorFile(remapTarget))){
|
||||
Log.info("Remapping sector: @ -> @ (@)", sector.id, remapTarget.id, remapTarget.preset);
|
||||
|
||||
sector.loadInfo();
|
||||
//overwrite the target sector's info with the save's info
|
||||
Core.settings.putJson(remapTarget.planet.name + "-s-" + remapTarget.id + "-info", sector.info);
|
||||
remapTarget.loadInfo();
|
||||
|
||||
//queue a clear of the sector that had its data moved
|
||||
infoToClear.add(sector);
|
||||
//add to the remapped list (if it was remapped, don't clear it!)
|
||||
remapped.add(remapTarget);
|
||||
|
||||
remapTarget.save = slot;
|
||||
try{
|
||||
Fi target = getSectorFile(remapTarget);
|
||||
//move over save file
|
||||
slot.file.moveTo(target);
|
||||
slot.file = target;
|
||||
SectorInfo info = Core.settings.getJson(sector.planet.name + "-s-" + sector.id + "-info", SectorInfo.class, SectorInfo::new);
|
||||
Fi tmpRemapFile = saveDirectory.child("remap_" + sector.planet.name + "_" + sector.id + "." + saveExtension);
|
||||
slot.file.moveTo(tmpRemapFile);
|
||||
|
||||
remaps.add(new Remap(slot, tmpRemapFile, sector, info, getSectorFile(remapTarget), remapTarget));
|
||||
remapped.add(remapTarget);
|
||||
}catch(Exception e){
|
||||
Log.err("Failed to move sector files when remapping: " + sector.id + " -> " + remapTarget.id, e);
|
||||
}
|
||||
@@ -125,6 +141,7 @@ public class Saves{
|
||||
|
||||
remapTarget.save = slot;
|
||||
slot.meta.rules.sector = remapTarget;
|
||||
|
||||
}else{
|
||||
if(sector.save != null){
|
||||
Log.warn("Sector @ has two corresponding saves: @ and @", sector, sector.save.file, slot.file);
|
||||
@@ -134,10 +151,27 @@ public class Saves{
|
||||
}
|
||||
}
|
||||
|
||||
for(var sector : infoToClear){
|
||||
if(!remapped.contains(sector)){
|
||||
sector.clearInfo();
|
||||
}
|
||||
//process remaps later to allow swaps of sectors
|
||||
for(var remap : remaps){
|
||||
var remapTarget = remap.destSector;
|
||||
|
||||
//overwrite the target sector's info with the save's info
|
||||
Core.settings.putJson(remapTarget.planet.name + "-s-" + remapTarget.id + "-info", remap.sourceInfo);
|
||||
remapTarget.loadInfo();
|
||||
|
||||
remapTarget.save = remap.slot;
|
||||
try{
|
||||
//move file from tmp directory back into the correct location
|
||||
remap.sourceFile.moveTo(remap.destFile);
|
||||
remap.slot.file = remap.destFile;
|
||||
}catch(Exception e){
|
||||
Log.err("Failed to move back sector files when remapping: " + remap.sourceSector.id + " -> " + remapTarget.id, e);
|
||||
}
|
||||
|
||||
//clear the info, assuming it wasn't a sector that got mapped to
|
||||
if(!remapped.contains(remap.sourceSector)){
|
||||
remap.sourceSector.clearInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class Schematics implements Loadable{
|
||||
|
||||
all.sort();
|
||||
|
||||
if(shadowBuffer == null){
|
||||
if(shadowBuffer == null && !headless){
|
||||
Core.app.post(() -> shadowBuffer = new FrameBuffer(maxSchematicSize + padding + 8, maxSchematicSize + padding + 8));
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,7 @@ public class Schematics implements Loadable{
|
||||
|
||||
/** Creates an array of build plans from a schematic's data, centered on the provided x+y coordinates. */
|
||||
public Seq<BuildPlan> toPlans(Schematic schem, int x, int y){
|
||||
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block, t.config).original(t.x, t.y, schem.width, schem.height))
|
||||
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block, t.config))
|
||||
.removeAll(s -> (!s.block.isVisible() && !(s.block instanceof CoreBlock)) || !s.block.unlockedNow()).sort(Structs.comparingInt(s -> -s.block.schematicPriority));
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ public class SectorInfo{
|
||||
public float secondsPassed;
|
||||
/** How many minutes this sector has been captured. */
|
||||
public float minutesCaptured;
|
||||
/** Light coverage in terms of radius. */
|
||||
public float lightCoverage;
|
||||
/** Display name. */
|
||||
public @Nullable String name;
|
||||
/** Displayed icon. */
|
||||
@@ -225,6 +227,15 @@ public class SectorInfo{
|
||||
damage = 0;
|
||||
hasSpawns = spawner.countSpawns() > 0;
|
||||
|
||||
lightCoverage = 0f;
|
||||
for(var build : state.rules.defaultTeam.data().buildings){
|
||||
if(build.block.emitLight){
|
||||
lightCoverage += build.block.lightRadius * build.efficiency;
|
||||
}
|
||||
}
|
||||
|
||||
lightCoverage += state.rules.defaultTeam.data().units.sumf(u -> u.type.lightRadius/2f);
|
||||
|
||||
//cap production at raw production.
|
||||
production.each((item, stat) -> {
|
||||
stat.mean = Math.min(stat.mean, rawProduction.get(item, ExportStat::new).mean);
|
||||
@@ -242,6 +253,10 @@ public class SectorInfo{
|
||||
if(sector.planet.allowWaveSimulation){
|
||||
SectorDamage.writeParameters(sector);
|
||||
}
|
||||
|
||||
if(sector.planet.generator != null){
|
||||
sector.planet.generator.beforeSaveWrite(sector);
|
||||
}
|
||||
}
|
||||
|
||||
/** Update averages of various stats, updates some special sector logic.
|
||||
|
||||
@@ -322,6 +322,13 @@ public class Universe{
|
||||
return net.client() ? netSeconds : seconds;
|
||||
}
|
||||
|
||||
public void setSeconds(float seconds){
|
||||
this.seconds = (int)seconds;
|
||||
this.secondCounter = seconds - this.seconds;
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
public float secondsf(){
|
||||
return seconds() + secondCounter;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LoadRenderer implements Disposable{
|
||||
private float testprogress = 0f;
|
||||
private StringBuilder assetText = new StringBuilder();
|
||||
private Bar[] bars;
|
||||
private Mesh mesh = MeshBuilder.buildHex(colorRed, 2, true, 1f);
|
||||
private Mesh mesh = MeshBuilder.buildPlanetGrid(PlanetGrid.create(2), colorRed, 1f);
|
||||
private Camera3D cam = new Camera3D();
|
||||
private int lastLength = -1;
|
||||
private FxProcessor fx;
|
||||
|
||||
@@ -109,6 +109,7 @@ public class Shaders{
|
||||
public Color ambientColor = Color.white.cpy();
|
||||
public Vec3 camDir = new Vec3();
|
||||
public Vec3 camPos = new Vec3();
|
||||
public boolean emissive;
|
||||
public Planet planet;
|
||||
|
||||
public PlanetShader(){
|
||||
@@ -123,6 +124,7 @@ public class Shaders{
|
||||
setUniformf("u_ambientColor", ambientColor.r, ambientColor.g, ambientColor.b);
|
||||
setUniformf("u_camdir", camDir);
|
||||
setUniformf("u_campos", renderer.planets.cam.position);
|
||||
setUniformf("u_emissive", emissive ? 1f : 0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package mindustry.graphics.g3d;
|
||||
|
||||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
|
||||
public interface GenericMesh{
|
||||
public interface GenericMesh extends Disposable{
|
||||
void render(PlanetParams params, Mat3D projection, Mat3D transform);
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ import mindustry.type.*;
|
||||
public class HexMesh extends PlanetMesh{
|
||||
|
||||
public HexMesh(Planet planet, int divisions){
|
||||
super(planet, MeshBuilder.buildHex(planet.generator, divisions, false, planet.radius, 0.2f), Shaders.planet);
|
||||
super(planet, MeshBuilder.buildHex(planet.generator, divisions, planet.radius, 0.2f), Shaders.planet);
|
||||
}
|
||||
|
||||
public HexMesh(Planet planet, HexMesher mesher, int divisions, Shader shader){
|
||||
super(planet, MeshBuilder.buildHex(mesher, divisions, false, planet.radius, 0.2f), shader);
|
||||
super(planet, MeshBuilder.buildHex(mesher, divisions, planet.radius, 0.2f), shader);
|
||||
}
|
||||
|
||||
public HexMesh(){
|
||||
@@ -21,6 +21,7 @@ public class HexMesh extends PlanetMesh{
|
||||
@Override
|
||||
public void preRender(PlanetParams params){
|
||||
Shaders.planet.planet = planet;
|
||||
Shaders.planet.emissive = planet.generator != null && planet.generator.isEmissive();
|
||||
Shaders.planet.lightDir.set(planet.solarSystem.position).sub(planet.position).rotate(Vec3.Y, planet.getRotation()).nor();
|
||||
Shaders.planet.ambientColor.set(planet.solarSystem.lightColor);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,23 @@ import arc.math.geom.*;
|
||||
|
||||
/** Defines color and height for a planet mesh. */
|
||||
public interface HexMesher{
|
||||
float getHeight(Vec3 position);
|
||||
Color getColor(Vec3 position);
|
||||
|
||||
default float getHeight(Vec3 position){
|
||||
return 0f;
|
||||
}
|
||||
|
||||
default void getColor(Vec3 position, Color out){
|
||||
|
||||
}
|
||||
|
||||
default void getEmissiveColor(Vec3 position, Color out){
|
||||
|
||||
}
|
||||
|
||||
default boolean isEmissive(){
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean skip(Vec3 position){
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -21,15 +21,15 @@ public class HexSkyMesh extends PlanetMesh{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
return color;
|
||||
public void getColor(Vec3 position, Color out){
|
||||
out.set(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean skip(Vec3 position){
|
||||
return Simplex.noise3d(7 + seed, octaves, persistence, scl, position.x, position.y * 3f, position.z) >= thresh;
|
||||
}
|
||||
}, divisions, false, planet.radius, radius), Shaders.clouds);
|
||||
}, divisions, planet.radius, radius), Shaders.clouds);
|
||||
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
@@ -19,4 +19,9 @@ public class MatMesh implements GenericMesh{
|
||||
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
|
||||
mesh.render(params, projection, tmp.set(transform).mul(mat));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(){
|
||||
mesh.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,72 @@
|
||||
package mindustry.graphics.g3d;
|
||||
|
||||
import arc.*;
|
||||
import arc.graphics.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.struct.*;
|
||||
import mindustry.graphics.g3d.PlanetGrid.*;
|
||||
import mindustry.maps.generators.*;
|
||||
|
||||
public class MeshBuilder{
|
||||
private static final Vec3 v1 = new Vec3(), v2 = new Vec3(), v3 = new Vec3(), v4 = new Vec3();
|
||||
private static final float[] floats = new float[3 + 3 + 1];
|
||||
private static Mesh mesh;
|
||||
|
||||
public static Mesh buildIcosphere(int divisions, float radius, Color color){
|
||||
begin(20 * (2 << (2 * divisions - 1)) * 3);
|
||||
private static final boolean gl30 = Core.gl30 != null;
|
||||
private static volatile float[] tmpHeights = new float[14580]; //highest amount of corners in vanilla
|
||||
|
||||
/** Note that the resulting icosphere does not have normals or a color. */
|
||||
public static Mesh buildIcosphere(int divisions, float radius){
|
||||
MeshResult result = Icosphere.create(divisions);
|
||||
for(int i = 0; i < result.indices.size; i+= 3){
|
||||
v1.set(result.vertices.items, result.indices.items[i] * 3).setLength(radius);
|
||||
v2.set(result.vertices.items, result.indices.items[i + 1] * 3).setLength(radius);
|
||||
v3.set(result.vertices.items, result.indices.items[i + 2] * 3).setLength(radius);
|
||||
|
||||
verts(v1, v3, v2, normal(v1, v2, v3).scl(-1f), color);
|
||||
Mesh mesh = begin(result.vertices.size / 3, result.indices.size, false, false);
|
||||
|
||||
if(result.vertices.size >= 65535) throw new RuntimeException("Due to index size limits, only meshes with a maximum of 65535 vertices are supported. If you want more than that, make your own non-indexed mesh builder.");
|
||||
|
||||
float[] items = result.vertices.items;
|
||||
for(int i = 0; i < result.vertices.size; i ++){
|
||||
items[i] *= radius;
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
mesh.getVerticesBuffer().put(items, 0, result.vertices.size);
|
||||
|
||||
public static Mesh buildIcosphere(int divisions, float radius){
|
||||
return buildIcosphere(divisions, radius, Color.white);
|
||||
short[] indices = new short[result.indices.size];
|
||||
for(int i = 0; i < result.indices.size; i++){
|
||||
indices[i] = (short)result.indices.items[i];
|
||||
}
|
||||
|
||||
mesh.getIndicesBuffer().put(indices);
|
||||
|
||||
return end(mesh);
|
||||
}
|
||||
|
||||
public static Mesh buildPlanetGrid(PlanetGrid grid, Color color, float scale){
|
||||
int total = 0;
|
||||
for(Ptile tile : grid.tiles){
|
||||
total += tile.corners.length * 2;
|
||||
}
|
||||
Mesh mesh = begin(grid.tiles.length * 12, 0, false, false);
|
||||
|
||||
float col = color.toFloatBits();
|
||||
float[] floats = new float[8];
|
||||
|
||||
begin(total);
|
||||
for(Ptile tile : grid.tiles){
|
||||
Corner[] c = tile.corners;
|
||||
for(int i = 0; i < c.length; i++){
|
||||
Vec3 a = v1.set(c[i].v).scl(scale);
|
||||
Vec3 b = v2.set(c[(i + 1) % c.length].v).scl(scale);
|
||||
|
||||
vert(a, Vec3.Z, color);
|
||||
vert(b, Vec3.Z, color);
|
||||
for(int i = 0; i < c.length; i++){
|
||||
Vec3 v1 = c[i].v;
|
||||
Vec3 v2 = c[(i + 1) % c.length].v;
|
||||
|
||||
floats[0] = v1.x * scale;
|
||||
floats[1] = v1.y * scale;
|
||||
floats[2] = v1.z * scale;
|
||||
floats[3] = col;
|
||||
|
||||
floats[4] = v2.x * scale;
|
||||
floats[5] = v2.y * scale;
|
||||
floats[6] = v2.z * scale;
|
||||
floats[7] = col;
|
||||
|
||||
mesh.getVerticesBuffer().put(floats);
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
return end(mesh);
|
||||
}
|
||||
|
||||
public static Mesh buildHex(Color color, int divisions, boolean lines, float radius){
|
||||
public static Mesh buildHex(Color color, int divisions, float radius){
|
||||
return buildHex(new HexMesher(){
|
||||
@Override
|
||||
public float getHeight(Vec3 position){
|
||||
@@ -58,20 +74,46 @@ public class MeshBuilder{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
return color;
|
||||
public void getColor(Vec3 position, Color out){
|
||||
out.set(color);
|
||||
}
|
||||
}, divisions, lines, radius, 0);
|
||||
}, divisions, radius, 0);
|
||||
}
|
||||
|
||||
public static Mesh buildHex(HexMesher mesher, int divisions, boolean lines, float radius, float intensity){
|
||||
//TODO: in principle this should not be synchronized, but I would rather not realloc tmpHeights every time, and it is unlikely that two planets will be reloading at the same time
|
||||
public static synchronized Mesh buildHex(HexMesher mesher, int divisions, float radius, float intensity){
|
||||
PlanetGrid grid = PlanetGrid.create(divisions);
|
||||
|
||||
//TODO: this is NOT thread safe, but in practice, it should never cause a problem
|
||||
if(mesher instanceof PlanetGenerator generator){
|
||||
generator.seed = generator.baseSeed;
|
||||
}
|
||||
|
||||
begin(grid.tiles.length * 12);
|
||||
boolean emit = mesher.isEmissive();
|
||||
|
||||
if(grid.tiles.length * 6 >= 65535) throw new RuntimeException("Due to index size limits, only meshes with a maximum of 65535 vertices are supported. If you want more than that, make your own non-indexed mesh builder.");
|
||||
|
||||
Mesh mesh = begin(grid.tiles.length * 6, grid.tiles.length * 4 * 3, true, emit);
|
||||
|
||||
float[] heights;
|
||||
|
||||
if(tmpHeights == null || tmpHeights.length < grid.corners.length){
|
||||
heights = tmpHeights = new float[grid.corners.length];
|
||||
}else{
|
||||
heights = tmpHeights;
|
||||
}
|
||||
|
||||
//cache heights in an array to prevent redundant calls to getHeight
|
||||
for(int i = 0; i < grid.corners.length; i++){
|
||||
heights[i] = (1f + mesher.getHeight(grid.corners[i].v) * intensity) * radius;
|
||||
}
|
||||
int position = 0;
|
||||
|
||||
short[] shorts = new short[12];
|
||||
float[] floats = new float[3 + (gl30 ? 1 : 3) + 1 + (emit ? 1 : 0)];
|
||||
Vec3 nor = new Vec3();
|
||||
|
||||
Color tmpCol = new Color();
|
||||
|
||||
for(Ptile tile : grid.tiles){
|
||||
if(mesher.skip(tile.v)){
|
||||
@@ -80,81 +122,155 @@ public class MeshBuilder{
|
||||
|
||||
Corner[] c = tile.corners;
|
||||
|
||||
for(Corner corner : c){
|
||||
corner.v.setLength((1f + mesher.getHeight(v2.set(corner.v)) * intensity) * radius);
|
||||
float
|
||||
h1 = heights[c[0].id],
|
||||
h2 = heights[c[2].id],
|
||||
h3 = heights[c[4].id];
|
||||
|
||||
Vec3
|
||||
v1 = c[0].v,
|
||||
v2 = c[2].v,
|
||||
v3 = c[4].v;
|
||||
|
||||
normal(
|
||||
v1.x * h1, v1.y * h1, v1.z * h1,
|
||||
v2.x * h2, v2.y * h2, v2.z * h2,
|
||||
v3.x * h3, v3.y * h3, v3.z * h3,
|
||||
nor);
|
||||
|
||||
tmpCol.set(1f, 1f, 1f, 1f);
|
||||
mesher.getColor(tile.v, tmpCol);
|
||||
float color = tmpCol.toFloatBits();
|
||||
|
||||
float emissive = 0f;
|
||||
|
||||
if(emit){
|
||||
tmpCol.set(0f, 0f, 0f, 0f);
|
||||
mesher.getEmissiveColor(tile.v, tmpCol);
|
||||
emissive = tmpCol.toFloatBits();
|
||||
}
|
||||
|
||||
Vec3 nor = normal(c[0].v, c[2].v, c[4].v);
|
||||
Color color = mesher.getColor(v2.set(tile.v));
|
||||
for(var corner : c){
|
||||
float height = heights[corner.id];
|
||||
|
||||
if(lines){
|
||||
nor.set(1f, 1f, 1f);
|
||||
|
||||
for(int i = 0; i < c.length; i++){
|
||||
Vec3 v1 = c[i].v;
|
||||
Vec3 v2 = c[(i + 1) % c.length].v;
|
||||
|
||||
vert(v1, nor, color);
|
||||
vert(v2, nor, color);
|
||||
}
|
||||
}else{
|
||||
verts(c[0].v, c[1].v, c[2].v, nor, color);
|
||||
verts(c[0].v, c[2].v, c[3].v, nor, color);
|
||||
verts(c[0].v, c[3].v, c[4].v, nor, color);
|
||||
|
||||
if(c.length > 5){
|
||||
verts(c[0].v, c[4].v, c[5].v, nor, color);
|
||||
}
|
||||
vert(mesh, floats, corner.v.x * height, corner.v.y * height, corner.v.z * height, nor, color, emissive);
|
||||
}
|
||||
|
||||
//restore mutated corners
|
||||
for(Corner corner : c){
|
||||
corner.v.nor();
|
||||
shorts[0] = (short)(position);
|
||||
shorts[1] = (short)(position + 1);
|
||||
shorts[2] = (short)(position + 2);
|
||||
|
||||
shorts[3] = (short)(position);
|
||||
shorts[4] = (short)(position + 2);
|
||||
shorts[5] = (short)(position + 3);
|
||||
|
||||
shorts[6] = (short)(position);
|
||||
shorts[7] = (short)(position + 3);
|
||||
shorts[8] = (short)(position + 4);
|
||||
|
||||
if(c.length > 5){
|
||||
shorts[9] = (short)(position);
|
||||
shorts[10] = (short)(position + 4);
|
||||
shorts[11] = (short)(position + 5);
|
||||
}
|
||||
|
||||
mesh.getIndicesBuffer().put(shorts, 0, c.length > 5 ? 12 : 9);
|
||||
position += c.length;
|
||||
}
|
||||
|
||||
return end();
|
||||
return end(mesh);
|
||||
}
|
||||
|
||||
private static void begin(int count){
|
||||
mesh = new Mesh(true, count, 0,
|
||||
VertexAttribute.position3,
|
||||
VertexAttribute.normal,
|
||||
VertexAttribute.color
|
||||
private static Mesh begin(int vertices, int indices, boolean normal, boolean emissive){
|
||||
Seq<VertexAttribute> attributes = Seq.with(
|
||||
VertexAttribute.position3
|
||||
);
|
||||
|
||||
if(normal){
|
||||
//only GL30 supports GL_INT_2_10_10_10_REV
|
||||
attributes.add(gl30 ? VertexAttribute.packedNormal : VertexAttribute.normal);
|
||||
}
|
||||
|
||||
attributes.add(VertexAttribute.color);
|
||||
|
||||
if(emissive){
|
||||
attributes.add(new VertexAttribute(4, GL20.GL_UNSIGNED_BYTE, true, "a_emissive"));
|
||||
}
|
||||
|
||||
Mesh mesh = new Mesh(true, vertices, indices, attributes.toArray(VertexAttribute.class));
|
||||
|
||||
mesh.getVerticesBuffer().limit(mesh.getVerticesBuffer().capacity());
|
||||
mesh.getVerticesBuffer().position(0);
|
||||
|
||||
if(indices > 0){
|
||||
mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().capacity());
|
||||
mesh.getIndicesBuffer().position(0);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private static Mesh end(){
|
||||
Mesh last = mesh;
|
||||
last.getVerticesBuffer().limit(last.getVerticesBuffer().position());
|
||||
mesh = null;
|
||||
return last;
|
||||
private static Mesh end(Mesh mesh){
|
||||
mesh.getVerticesBuffer().limit(mesh.getVerticesBuffer().position());
|
||||
if(mesh.getNumIndices() > 0){
|
||||
mesh.getIndicesBuffer().limit(mesh.getIndicesBuffer().position());
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private static Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3){
|
||||
return v4.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
||||
private static Vec3 normal(Vec3 v1, Vec3 v2, Vec3 v3, Vec3 out){
|
||||
return out.set(v2).sub(v1).crs(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).nor();
|
||||
}
|
||||
|
||||
private static void verts(Vec3 a, Vec3 b, Vec3 c, Vec3 normal, Color color){
|
||||
vert(a, normal, color);
|
||||
vert(b, normal, color);
|
||||
vert(c, normal, color);
|
||||
private static void normal(float v1x, float v1y, float v1z, float v2x, float v2y, float v2z, float v3x, float v3y, float v3z, Vec3 out){
|
||||
float
|
||||
x = v2x - v1x,
|
||||
y = v2y - v1y,
|
||||
z = v2z - v1z,
|
||||
vx = v3x - v1x,
|
||||
vy = v3y - v1y,
|
||||
vz = v3z - v1z;
|
||||
|
||||
float
|
||||
cx = y * vz - z * vy,
|
||||
cy = z * vx - x * vz,
|
||||
cz = x * vy - y * vx;
|
||||
|
||||
out.set(cx, cy, cz).nor();
|
||||
}
|
||||
|
||||
private static void vert(Vec3 a, Vec3 normal, Color color){
|
||||
floats[0] = a.x;
|
||||
floats[1] = a.y;
|
||||
floats[2] = a.z;
|
||||
private static void vert(Mesh mesh, float[] floats, float x, float y, float z, Vec3 normal, float color, float emissive){
|
||||
floats[0] = x;
|
||||
floats[1] = y;
|
||||
floats[2] = z;
|
||||
|
||||
floats[3] = normal.x;
|
||||
floats[4] = normal.y;
|
||||
floats[5] = normal.z;
|
||||
if(gl30){
|
||||
floats[3] = packNormals(normal.x, normal.y, normal.z);
|
||||
|
||||
floats[4] = color;
|
||||
if(floats.length > 5) floats[5] = emissive;
|
||||
}else{
|
||||
floats[3] = normal.x;
|
||||
floats[4] = normal.x;
|
||||
floats[5] = normal.x;
|
||||
|
||||
floats[6] = color;
|
||||
if(floats.length > 7) floats[7] = emissive;
|
||||
}
|
||||
|
||||
floats[6] = color.toFloatBits();
|
||||
mesh.getVerticesBuffer().put(floats);
|
||||
}
|
||||
|
||||
private static float packNormals(float x, float y, float z){
|
||||
int xs = x < -1f/512f ? 1 : 0;
|
||||
int ys = y < -1f/512f ? 1 : 0;
|
||||
int zs = z < -1f/512f ? 1 : 0;
|
||||
|
||||
int vi =
|
||||
zs << 29 | ((int)(z * 511 + (zs << 9)) & 511) << 20 |
|
||||
ys << 19 | ((int)(y * 511 + (ys << 9)) & 511) << 10 |
|
||||
xs << 9 | ((int)(x * 511 + (xs << 9)) & 511);
|
||||
return Float.intBitsToFloat(vi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,11 @@ public class MultiMesh implements GenericMesh{
|
||||
v.render(params, projection, transform);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(){
|
||||
for(var mesh : meshes){
|
||||
mesh.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,10 @@ public class NoiseMesh extends HexMesh{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
return color;
|
||||
public void getColor(Vec3 position, Color out){
|
||||
out.set(color);
|
||||
}
|
||||
}, divisions, false, radius, 0.2f);
|
||||
}, divisions, radius, 0.2f);
|
||||
}
|
||||
|
||||
/** Two-color variant. */
|
||||
@@ -35,9 +35,9 @@ public class NoiseMesh extends HexMesh{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
return Simplex.noise3d(8 + seed, coct, cper, cscl, 5f + position.x, 5f + position.y, 5f + position.z) > cthresh ? color2 : color1;
|
||||
public void getColor(Vec3 position, Color out){
|
||||
out.set(Simplex.noise3d(8 + seed, coct, cper, cscl, 5f + position.x, 5f + position.y, 5f + position.z) > cthresh ? color2 : color1);
|
||||
}
|
||||
}, divisions, false, radius, 0.2f);
|
||||
}, divisions, radius, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class PlanetGrid{
|
||||
}
|
||||
}
|
||||
|
||||
public static PlanetGrid create(int size){
|
||||
public static synchronized PlanetGrid create(int size){
|
||||
//cache grids between calls, since only ~5 different grids total are needed
|
||||
if(size < cache.length && cache[size] != null){
|
||||
return cache[size];
|
||||
@@ -240,6 +240,14 @@ public class PlanetGrid{
|
||||
corners = new Corner[edgeCount];
|
||||
edges = new Edge[edgeCount];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Ptile{" +
|
||||
"id=" + id +
|
||||
" " + v +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class Corner{
|
||||
|
||||
@@ -26,6 +26,8 @@ public abstract class PlanetMesh implements GenericMesh{
|
||||
|
||||
@Override
|
||||
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
|
||||
if(mesh.isDisposed()) return;
|
||||
|
||||
preRender(params);
|
||||
shader.bind();
|
||||
shader.setUniformMatrix4("u_proj", projection.val);
|
||||
@@ -33,4 +35,9 @@ public abstract class PlanetMesh implements GenericMesh{
|
||||
shader.apply();
|
||||
mesh.render(shader, Gl.triangles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(){
|
||||
mesh.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class PlanetRenderer implements Disposable{
|
||||
setThreshold(0.8f);
|
||||
blurPasses = 6;
|
||||
}};
|
||||
public final Mesh atmosphere = MeshBuilder.buildHex(Color.white, 2, false, 1.5f);
|
||||
public final Mesh atmosphere = MeshBuilder.buildHex(Color.white, 2, 1.5f);
|
||||
|
||||
//seed: 8kmfuix03fw
|
||||
public final CubemapMesh skybox = new CubemapMesh(new Cubemap("cubemaps/stars/"));
|
||||
|
||||
@@ -3,7 +3,6 @@ package mindustry.graphics.g3d;
|
||||
import arc.graphics.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
import arc.util.noise.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
@@ -19,9 +18,9 @@ public class SunMesh extends HexMesh{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
public void getColor(Vec3 position, Color out){
|
||||
double height = Math.pow(Simplex.noise3d(0, octaves, persistence, scl, position.x, position.y, position.z), pow) * mag;
|
||||
return Tmp.c1.set(colors[Mathf.clamp((int)(height * colors.length), 0, colors.length - 1)]).mul(colorScale);
|
||||
out.set(colors[Mathf.clamp((int)(height * colors.length), 0, colors.length - 1)]).mul(colorScale);
|
||||
}
|
||||
}, divisions, Shaders.unlit);
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@ public class DesktopInput extends InputHandler{
|
||||
/** Time of most recent control group selection */
|
||||
public long lastCtrlGroupSelectMillis;
|
||||
|
||||
/** Time of most recent payload pickup/drop key press*/
|
||||
public long lastPayloadKeyTapMillis;
|
||||
/** Time of most recent payload pickup/drop key hold*/
|
||||
public long lastPayloadKeyHoldMillis;
|
||||
|
||||
private float buildPlanMouseOffsetX, buildPlanMouseOffsetY;
|
||||
private boolean changedCursor;
|
||||
|
||||
@@ -425,10 +430,6 @@ public class DesktopInput extends InputHandler{
|
||||
}
|
||||
}
|
||||
|
||||
if(Core.input.keyRelease(Binding.select)){
|
||||
player.shooting = false;
|
||||
}
|
||||
|
||||
if(state.isGame() && !scene.hasDialog() && !scene.hasField()){
|
||||
if(Core.input.keyTap(Binding.minimap)) ui.minimapfrag.toggle();
|
||||
if(Core.input.keyTap(Binding.planetMap) && state.isCampaign()) ui.planet.toggle();
|
||||
@@ -555,6 +556,10 @@ public class DesktopInput extends InputHandler{
|
||||
changedCursor = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(Core.input.keyRelease(Binding.select)){
|
||||
player.shooting = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -728,6 +733,7 @@ public class DesktopInput extends InputHandler{
|
||||
mode = none;
|
||||
}else if(!selectPlans.isEmpty()){
|
||||
flushPlans(selectPlans);
|
||||
movedPlan = true;
|
||||
}else if(isPlacing()){
|
||||
selectX = cursorX;
|
||||
selectY = cursorY;
|
||||
@@ -970,10 +976,26 @@ public class DesktopInput extends InputHandler{
|
||||
if(unit instanceof Payloadc){
|
||||
if(Core.input.keyTap(Binding.pickupCargo)){
|
||||
tryPickupPayload();
|
||||
lastPayloadKeyTapMillis = Time.millis();
|
||||
}
|
||||
|
||||
if(Core.input.keyDown(Binding.pickupCargo)
|
||||
&& Time.timeSinceMillis(lastPayloadKeyHoldMillis) > 20
|
||||
&& Time.timeSinceMillis(lastPayloadKeyTapMillis) > 200){
|
||||
tryPickupPayload();
|
||||
lastPayloadKeyHoldMillis = Time.millis();
|
||||
}
|
||||
|
||||
if(Core.input.keyTap(Binding.dropCargo)){
|
||||
tryDropPayload();
|
||||
lastPayloadKeyTapMillis = Time.millis();
|
||||
}
|
||||
|
||||
if(Core.input.keyDown(Binding.dropCargo)
|
||||
&& Time.timeSinceMillis(lastPayloadKeyHoldMillis) > 20
|
||||
&& Time.timeSinceMillis(lastPayloadKeyTapMillis) > 200){
|
||||
tryDropPayload();
|
||||
lastPayloadKeyHoldMillis = Time.millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1331,9 +1331,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
plans.each(plan -> {
|
||||
if(plan.breaking) return;
|
||||
|
||||
float off = plan.block.size % 2 == 0 ? -0.5f : 0f;
|
||||
|
||||
plan.pointConfig(p -> {
|
||||
int cx = p.x, cy = p.y;
|
||||
int lx = cx;
|
||||
float cx = p.x + off, cy = p.y + off;
|
||||
float lx = cx;
|
||||
|
||||
if(direction >= 0){
|
||||
cx = -cy;
|
||||
@@ -1342,7 +1344,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
cx = cy;
|
||||
cy = -lx;
|
||||
}
|
||||
p.set(cx, cy);
|
||||
p.set(Mathf.floor(cx - off), Mathf.floor(cy - off));
|
||||
});
|
||||
|
||||
//rotate actual plan, centered on its multiblock position
|
||||
@@ -1376,14 +1378,12 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
|
||||
plan.pointConfig(p -> {
|
||||
int corigin = x ? plan.originalWidth/2 : plan.originalHeight/2;
|
||||
int nvalue = -(x ? p.x : p.y);
|
||||
if(x){
|
||||
plan.originalX = -(plan.originalX - corigin) + corigin;
|
||||
p.x = nvalue;
|
||||
if(plan.block.size % 2 == 0) p.x --;
|
||||
p.x = -p.x;
|
||||
}else{
|
||||
plan.originalY = -(plan.originalY - corigin) + corigin;
|
||||
p.y = nvalue;
|
||||
if(plan.block.size % 2 == 0) p.y --;
|
||||
p.y = -p.y;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
}else{
|
||||
Building tile = world.buildWorld(x, y);
|
||||
|
||||
if((tile != null && player.team() != tile.team && (tile.team != Team.derelict || state.rules.coreCapture)) || (tile != null && player.unit().type.canHeal && tile.team == player.team() && tile.damaged())){
|
||||
if((tile != null && (player.team() != tile.team && (tile.team != Team.derelict || state.rules.coreCapture)) && player.unit().type.canAttack) || (tile != null && player.unit().type.canHeal && tile.team == player.team() && tile.damaged())){
|
||||
player.unit().mineTile = null;
|
||||
target = tile;
|
||||
}
|
||||
@@ -1078,7 +1078,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
//this may be a bad idea, aiming for a point far in front could work better, test it out
|
||||
unit.aim(Core.input.mouseWorldX(), Core.input.mouseWorldY());
|
||||
}else{
|
||||
Vec2 intercept = Predict.intercept(unit, target, bulletSpeed);
|
||||
Vec2 intercept = player.unit().type.weapons.contains(w -> w.predictTarget) ? Predict.intercept(unit, target, bulletSpeed) : Tmp.v1.set(target);
|
||||
|
||||
player.mouseX = intercept.x;
|
||||
player.mouseY = intercept.y;
|
||||
|
||||
@@ -172,7 +172,7 @@ public class MapIO{
|
||||
for(Tile tile : tiles){
|
||||
//while synthetic blocks are possible, most of their data is lost, so in order to avoid questions like
|
||||
//"why is there air under my drill" and "why are all my conveyors facing right", they are disabled
|
||||
int color = tile.block().hasColor && !tile.block().synthetic() ? tile.block().mapColor.rgba() : tile.floor().mapColor.rgba();
|
||||
int color = tile.block().hasColor && !tile.block().hasBuilding() ? tile.block().mapColor.rgba() : tile.floor().mapColor.rgba();
|
||||
pix.set(tile.x, tiles.height - 1 - tile.y, color);
|
||||
}
|
||||
return pix;
|
||||
@@ -183,6 +183,9 @@ public class MapIO{
|
||||
int color = pixmap.get(tile.x, pixmap.height - 1 - tile.y);
|
||||
Block block = ColorMapper.get(color);
|
||||
|
||||
//ignore buildings; reading images is only intended for environment tiles
|
||||
if(block.hasBuilding()) continue;
|
||||
|
||||
if(block.isOverlay()){
|
||||
tile.setOverlay(block.asFloor());
|
||||
}else if(block.isFloor()){
|
||||
@@ -194,7 +197,6 @@ public class MapIO{
|
||||
}
|
||||
}
|
||||
|
||||
//guess at floors by grabbing a random adjacent floor
|
||||
for(Tile tile : tiles){
|
||||
//default to stone floor
|
||||
if(tile.floor() == Blocks.air){
|
||||
|
||||
@@ -1104,7 +1104,7 @@ public class TypeIO{
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents a unit that has not been resolved yet. TODO unimplemented / unused*/
|
||||
/** Represents a unit that has not been resolved yet. */
|
||||
public static class UnitBox implements Boxed<Unit>{
|
||||
public int id;
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public enum LAccess{
|
||||
displayWidth,
|
||||
displayHeight,
|
||||
bufferUsage,
|
||||
operations,
|
||||
size,
|
||||
solid,
|
||||
dead,
|
||||
|
||||
@@ -25,6 +25,7 @@ import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.environment.*;
|
||||
import mindustry.world.blocks.logic.*;
|
||||
import mindustry.world.blocks.logic.CanvasBlock.*;
|
||||
import mindustry.world.blocks.logic.LogicBlock.*;
|
||||
import mindustry.world.blocks.logic.LogicDisplay.*;
|
||||
import mindustry.world.blocks.logic.MemoryBlock.*;
|
||||
@@ -581,6 +582,8 @@ public class LExecutor{
|
||||
}
|
||||
}else if(target.isobj && target.objval instanceof CharSequence str){
|
||||
output.setnum(address < 0 || address >= str.length() ? Double.NaN : (int)str.charAt(address));
|
||||
}else if(from instanceof CanvasBuild canvas && (exec.privileged || (from.team == exec.team))){
|
||||
output.setnum(canvas.getPixel(address));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,6 +614,8 @@ public class LExecutor{
|
||||
toVar.numval = value.numval;
|
||||
toVar.isobj = value.isobj;
|
||||
}
|
||||
}else if(from instanceof CanvasBuild canvas && (exec.privileged || (from.team == exec.team))){
|
||||
canvas.setPixel(address, value.numi());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public enum LMarkerControl{
|
||||
color("color"),
|
||||
radius("radius"),
|
||||
stroke("stroke"),
|
||||
outline("outline"),
|
||||
rotation("rotation"),
|
||||
shape("sides", "fill", "outline"),
|
||||
arc("start", "end"),
|
||||
|
||||
@@ -221,7 +221,7 @@ public class LogicDialog extends BaseDialog{
|
||||
update(() -> setColor(typeColor(s, color)));
|
||||
}}, new Label(() -> " " + typeName(s) + " "){{
|
||||
setStyle(Styles.outlineLabel);
|
||||
}});
|
||||
}}).minWidth(120f);
|
||||
|
||||
t.row();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ public enum LogicOp{
|
||||
div("/", (a, b) -> a / b),
|
||||
idiv("//", (a, b) -> Math.floor(a / b)),
|
||||
mod("%", (a, b) -> a % b),
|
||||
emod("%%", (a, b) -> ((a % b) + b) % b),
|
||||
pow("^", Math::pow),
|
||||
|
||||
equal("==", (a, b) -> Math.abs(a - b) < 0.000001 ? 1 : 0, (a, b) -> Structs.eq(a, b) ? 1 : 0),
|
||||
@@ -24,6 +25,7 @@ public enum LogicOp{
|
||||
|
||||
shl("<<", (a, b) -> (long)a << (long)b),
|
||||
shr(">>", (a, b) -> (long)a >> (long)b),
|
||||
ushr(">>>", (a, b) -> (long)a >>> (long)b),
|
||||
or("or", (a, b) -> (long)a | (long)b),
|
||||
and("b-and", (a, b) -> (long)a & (long)b),
|
||||
xor("xor", (a, b) -> (long)a ^ (long)b),
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package mindustry.maps;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
/** Class for temporarily (?) storing links to map submissions on Discord. */
|
||||
public class SectorSubmissions{
|
||||
private static IntMap<String> hiddenMap = new IntMap<>();
|
||||
|
||||
static{
|
||||
//autogenerated
|
||||
hiddenMap.put(0, "https://discord.com/channels/391020510269669376/1379926780860698784");
|
||||
hiddenMap.put(6, "https://discord.com/channels/391020510269669376/1379926782966497322");
|
||||
hiddenMap.put(13, "https://discord.com/channels/391020510269669376/1379926785164312810");
|
||||
hiddenMap.put(16, "https://discord.com/channels/391020510269669376/1379926788280680579");
|
||||
hiddenMap.put(19, "https://discord.com/channels/391020510269669376/1379926792479183019");
|
||||
hiddenMap.put(20, "https://discord.com/channels/391020510269669376/1379926794114961634");
|
||||
hiddenMap.put(24, "https://discord.com/channels/391020510269669376/1379926797042581716");
|
||||
hiddenMap.put(27, "https://discord.com/channels/391020510269669376/1379926798833287289");
|
||||
hiddenMap.put(30, "https://discord.com/channels/391020510269669376/1379926800854945823");
|
||||
hiddenMap.put(47, "https://discord.com/channels/391020510269669376/1379926802591645820");
|
||||
hiddenMap.put(55, "https://discord.com/channels/391020510269669376/1379926823277695189");
|
||||
hiddenMap.put(66, "https://discord.com/channels/391020510269669376/1379926825941078128");
|
||||
hiddenMap.put(67, "https://discord.com/channels/391020510269669376/1379926828696866898");
|
||||
hiddenMap.put(69, "https://discord.com/channels/391020510269669376/1379926831326822610");
|
||||
hiddenMap.put(76, "https://discord.com/channels/391020510269669376/1379926833411391580");
|
||||
hiddenMap.put(92, "https://discord.com/channels/391020510269669376/1379926835621527615");
|
||||
hiddenMap.put(94, "https://discord.com/channels/391020510269669376/1379926838079393802");
|
||||
hiddenMap.put(103, "https://discord.com/channels/391020510269669376/1379926839559979030");
|
||||
hiddenMap.put(111, "https://discord.com/channels/391020510269669376/1379926842659569864");
|
||||
hiddenMap.put(116, "https://discord.com/channels/391020510269669376/1379926845058711734");
|
||||
hiddenMap.put(127, "https://discord.com/channels/391020510269669376/1379926869465632829");
|
||||
hiddenMap.put(133, "https://discord.com/channels/391020510269669376/1379926871227240770");
|
||||
hiddenMap.put(138, "https://discord.com/channels/391020510269669376/1379926873152164004");
|
||||
hiddenMap.put(150, "https://discord.com/channels/391020510269669376/1379926876457537547");
|
||||
hiddenMap.put(157, "https://discord.com/channels/391020510269669376/1379926879502598155");
|
||||
hiddenMap.put(161, "https://discord.com/channels/391020510269669376/1379926882203730024");
|
||||
hiddenMap.put(162, "https://discord.com/channels/391020510269669376/1379926884606808247");
|
||||
hiddenMap.put(176, "https://discord.com/channels/391020510269669376/1379926887203213353");
|
||||
hiddenMap.put(180, "https://discord.com/channels/391020510269669376/1379926889648619580");
|
||||
hiddenMap.put(185, "https://discord.com/channels/391020510269669376/1379926892181983283");
|
||||
hiddenMap.put(191, "https://discord.com/channels/391020510269669376/1379926912004001914");
|
||||
hiddenMap.put(192, "https://discord.com/channels/391020510269669376/1379926914122256449");
|
||||
hiddenMap.put(197, "https://discord.com/channels/391020510269669376/1379926916911599676");
|
||||
hiddenMap.put(200, "https://discord.com/channels/391020510269669376/1379926918429806755");
|
||||
hiddenMap.put(204, "https://discord.com/channels/391020510269669376/1379926921130807447");
|
||||
hiddenMap.put(207, "https://discord.com/channels/391020510269669376/1379926923370827827");
|
||||
hiddenMap.put(225, "https://discord.com/channels/391020510269669376/1379926925719376152");
|
||||
hiddenMap.put(230, "https://discord.com/channels/391020510269669376/1379926927585841163");
|
||||
hiddenMap.put(237, "https://discord.com/channels/391020510269669376/1379926929636851812");
|
||||
hiddenMap.put(242, "https://discord.com/channels/391020510269669376/1379926931923013843");
|
||||
hiddenMap.put(243, "https://discord.com/channels/391020510269669376/1379926955423694978");
|
||||
hiddenMap.put(244, "https://discord.com/channels/391020510269669376/1379926957738954762");
|
||||
hiddenMap.put(245, "https://discord.com/channels/391020510269669376/1379926971286290584");
|
||||
hiddenMap.put(246, "https://discord.com/channels/391020510269669376/1379926973454745600");
|
||||
hiddenMap.put(247, "https://discord.com/channels/391020510269669376/1379926976361533752");
|
||||
hiddenMap.put(248, "https://discord.com/channels/391020510269669376/1379926979129774151");
|
||||
hiddenMap.put(251, "https://discord.com/channels/391020510269669376/1379928042637361382");
|
||||
hiddenMap.put(254, "https://discord.com/channels/391020510269669376/1379928045577703424");
|
||||
hiddenMap.put(259, "https://discord.com/channels/391020510269669376/1379928048245280871");
|
||||
hiddenMap.put(263, "https://discord.com/channels/391020510269669376/1379928050010951694");
|
||||
hiddenMap.put(265, "https://discord.com/channels/391020510269669376/1379928052921929891");
|
||||
}
|
||||
|
||||
/** @return the link to the Discord discussion thread of the specified hidden sector submission. */
|
||||
public static @Nullable String getSectorThread(Sector sector){
|
||||
if(sector.generateEnemyBase){
|
||||
return hiddenMap.get(sector.id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package mindustry.maps.generators;
|
||||
|
||||
import arc.graphics.*;
|
||||
import arc.math.geom.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
@@ -9,16 +7,6 @@ import mindustry.world.*;
|
||||
/** A planet generator that provides no weather, height, color or bases. Override generate().*/
|
||||
public class BlankPlanetGenerator extends PlanetGenerator{
|
||||
|
||||
@Override
|
||||
public float getHeight(Vec3 position){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
return Color.white;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWeather(Sector sector, Rules rules){
|
||||
|
||||
|
||||
@@ -25,11 +25,22 @@ public abstract class PlanetGenerator extends BasicGenerator implements HexMeshe
|
||||
|
||||
protected @Nullable Sector sector;
|
||||
|
||||
/** Should generate sector bases for a planet. */
|
||||
public void generateSector(Sector sector){
|
||||
|
||||
}
|
||||
|
||||
public void onSectorCaptured(Sector sector){
|
||||
|
||||
}
|
||||
|
||||
public void onSectorLost(Sector sector){
|
||||
|
||||
}
|
||||
|
||||
public void beforeSaveWrite(Sector sector){
|
||||
|
||||
}
|
||||
|
||||
public void getLockedText(Sector hovered, StringBuilder out){
|
||||
out.append("[gray]").append(Iconc.lock).append(" ").append(Core.bundle.get("locked"));
|
||||
}
|
||||
|
||||
@@ -39,20 +39,17 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
public void getColor(Vec3 position, Color out){
|
||||
Block block = getBlock(position);
|
||||
|
||||
//more obvious color
|
||||
if(block == Blocks.crystallineStone) block = Blocks.crystalFloor;
|
||||
//TODO this might be too green
|
||||
//if(block == Blocks.beryllicStone) block = Blocks.arkyicStone;
|
||||
|
||||
return Tmp.c1.set(block.mapColor).a(1f - block.albedo);
|
||||
out.set(block.mapColor).a(1f - block.albedo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSizeScl(){
|
||||
//TODO should sectors be 600, or 500 blocks?
|
||||
return 2000 * 1.07f * 6f / 5f;
|
||||
}
|
||||
|
||||
@@ -65,17 +62,17 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
||||
}
|
||||
|
||||
Block getBlock(Vec3 position){
|
||||
float ice = rawTemp(position);
|
||||
Tmp.v32.set(position);
|
||||
float px = position.x, py = position.y, pz = position.z;
|
||||
|
||||
float ice = rawTemp(position);
|
||||
float height = rawHeight(position);
|
||||
Tmp.v31.set(position);
|
||||
|
||||
height *= 1.2f;
|
||||
height = Mathf.clamp(height);
|
||||
|
||||
Block result = terrain[Mathf.clamp((int)(height * terrain.length), 0, terrain.length - 1)];
|
||||
|
||||
if(ice < 0.3 + Math.abs(Ridged.noise3d(seed + crystalSeed, position.x + 4f, position.y + 8f, position.z + 1f, crystalOct, crystalScl)) * crystalMag){
|
||||
if(ice < 0.3 + Math.abs(Ridged.noise3d(seed + crystalSeed, px + 4f, py + 8f, pz + 1f, crystalOct, crystalScl)) * crystalMag){
|
||||
return Blocks.crystallineStone;
|
||||
}
|
||||
|
||||
@@ -86,11 +83,9 @@ public class ErekirPlanetGenerator extends PlanetGenerator{
|
||||
}
|
||||
}
|
||||
|
||||
position = Tmp.v32;
|
||||
|
||||
//TODO tweak this to make it more natural
|
||||
//TODO edge distortion?
|
||||
if(ice < redThresh - noArkThresh && Ridged.noise3d(seed + arkSeed, position.x + 2f, position.y + 8f, position.z + 1f, arkOct, arkScl) > arkThresh){
|
||||
if(ice < redThresh - noArkThresh && Ridged.noise3d(seed + arkSeed, px + 2f, py + 8f, pz + 1f, arkOct, arkScl) > arkThresh){
|
||||
//TODO arkyic in middle
|
||||
result = Blocks.beryllicStone;
|
||||
}
|
||||
|
||||
@@ -20,13 +20,16 @@ import mindustry.world.blocks.environment.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class SerpuloPlanetGenerator extends PlanetGenerator{
|
||||
//alternate, less direct generation (wip)
|
||||
public static boolean alt = false;
|
||||
//alternate, less direct generation
|
||||
public static boolean indirectPaths = false;
|
||||
//random water patches
|
||||
public static boolean genLakes = false;
|
||||
|
||||
BaseGenerator basegen = new BaseGenerator();
|
||||
float heightYOffset = 42.7f;
|
||||
float scl = 5f;
|
||||
float waterOffset = 0.05f;
|
||||
boolean genLakes = false;
|
||||
float waterOffset = 0.04f;
|
||||
float heightScl = 1.01f;
|
||||
|
||||
Block[][] arr =
|
||||
{
|
||||
@@ -58,10 +61,30 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
||||
);
|
||||
|
||||
float water = 2f / arr[0].length;
|
||||
Vec3 basePos = new Vec3(0.9341721, 0.0, 0.3568221);
|
||||
|
||||
float rawHeight(Vec3 position){
|
||||
position = Tmp.v33.set(position).scl(scl);
|
||||
return (Mathf.pow(Simplex.noise3d(seed, 7, 0.5f, 1f/3f, position.x, position.y, position.z), 2.3f) + waterOffset) / (1f + waterOffset);
|
||||
return (Mathf.pow(Simplex.noise3d(seed, 7, 0.5f, 1f/3f, position.x * scl, position.y * scl + heightYOffset, position.z * scl) * heightScl, 2.3f) + waterOffset) / (1f + waterOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSectorCaptured(Sector sector){
|
||||
sector.planet.reloadMeshAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSectorLost(Sector sector){
|
||||
sector.planet.reloadMeshAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeSaveWrite(Sector sector){
|
||||
sector.planet.reloadMeshAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmissive(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,16 +109,57 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
public void getColor(Vec3 position, Color out){
|
||||
Block block = getBlock(position);
|
||||
//replace salt with sand color
|
||||
if(block == Blocks.salt) return Blocks.sand.mapColor;
|
||||
return Tmp.c1.set(block.mapColor).a(1f - block.albedo);
|
||||
if(block == Blocks.salt) block = Blocks.sand;
|
||||
out.set(block.mapColor).a(1f - block.albedo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getEmissiveColor(Vec3 position, Color out){
|
||||
float dst = 999f, captureDst = 999f, lightScl = 0f;
|
||||
|
||||
Object[] sectors = Planets.serpulo.sectors.items;
|
||||
int size = Planets.serpulo.sectors.size;
|
||||
|
||||
for(int i = 0; i < size; i ++){
|
||||
var sector = (Sector)sectors[i];
|
||||
|
||||
if(sector.hasEnemyBase() && !sector.isCaptured()){
|
||||
dst = Math.min(dst, position.dst(sector.tile.v) - (sector.preset != null ? sector.preset.difficulty/10f * 0.03f - 0.03f : 0f));
|
||||
}else if(sector.hasBase()){
|
||||
float cdst = position.dst(sector.tile.v);
|
||||
if(cdst < captureDst){
|
||||
captureDst = cdst;
|
||||
lightScl = sector.info.lightCoverage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lightScl = Math.min(lightScl / 50000f, 1.3f);
|
||||
if(lightScl < 1f) lightScl = Interp.pow5Out.apply(lightScl);
|
||||
|
||||
float freq = 0.05f;
|
||||
if(position.dst(basePos) < 0.55f ?
|
||||
|
||||
dst*metalDstScl + Simplex.noise3d(seed + 1, 3, 0.4, 5.5f, position.x, position.y + 200f, position.z)*0.08f + ((basePos.dst(position) + 0.00f) % freq < freq/2f ? 1f : 0f) * 0.07f < 0.08f/* || dst <= 0.0001f*/ :
|
||||
dst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 9f, position.x, position.y + 370f, position.z)*0.06f < 0.045){
|
||||
|
||||
out.set(Team.crux.color)
|
||||
.mul(0.8f + Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 99f, position.z) * 0.4f)
|
||||
.lerp(Team.sharded.color, 0.2f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)).toFloatBits();
|
||||
}else if(captureDst*metalDstScl + Simplex.noise3d(seed, 3, 0.4, 9f, position.x, position.y + 600f, position.z)*0.07f < 0.05 * lightScl){
|
||||
out.set(Team.sharded.color).mul(0.7f + Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 99f, position.z) * 0.4f)
|
||||
.lerp(Team.crux.color, 0.3f*Simplex.noise3d(seed, 1, 1, 9f, position.x, position.y + 999f, position.z)).toFloatBits();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genTile(Vec3 position, TileGen tile){
|
||||
tile.floor = getBlock(position);
|
||||
if(tile.floor == Blocks.darkPanel6) tile.floor = Blocks.darkPanel3;
|
||||
tile.block = tile.floor.asFloor().wall;
|
||||
|
||||
if(Ridged.noise3d(seed + 1, position.x, position.y, position.z, 2, 22) > 0.31){
|
||||
@@ -103,23 +167,46 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
||||
}
|
||||
}
|
||||
|
||||
static double metalDstScl = 0.25;
|
||||
|
||||
Block getBlock(Vec3 position){
|
||||
float height = rawHeight(position);
|
||||
Tmp.v31.set(position);
|
||||
position = Tmp.v33.set(position).scl(scl);
|
||||
float px = position.x * scl, py = position.y * scl, pz = position.z * scl;
|
||||
|
||||
float rad = scl;
|
||||
float temp = Mathf.clamp(Math.abs(position.y * 2f) / (rad));
|
||||
float tnoise = Simplex.noise3d(seed, 7, 0.56, 1f/3f, position.x, position.y + 999f, position.z);
|
||||
float temp = Mathf.clamp(Math.abs(py * 2f) / (rad));
|
||||
float tnoise = Simplex.noise3d(seed, 7, 0.56, 1f/3f, px, py + 999f - 0.1f, pz);
|
||||
temp = Mathf.lerp(temp, tnoise, 0.5f);
|
||||
height *= 1.2f;
|
||||
height = Mathf.clamp(height);
|
||||
|
||||
float tar = Simplex.noise3d(seed, 4, 0.55f, 1f/2f, position.x, position.y + 999f, position.z) * 0.3f + Tmp.v31.dst(0, 0, 1f) * 0.2f;
|
||||
float tar = Simplex.noise3d(seed, 4, 0.55f, 1f/2f, px, py + 999f, pz) * 0.3f + position.dst(0, 0, 1f) * 0.2f;
|
||||
|
||||
Block res = arr[Mathf.clamp((int)(temp * arr.length), 0, arr[0].length - 1)][Mathf.clamp((int)(height * arr[0].length), 0, arr[0].length - 1)];
|
||||
if(tar > 0.5f){
|
||||
return tars.get(res, res);
|
||||
}else{
|
||||
if(position.within(basePos, 0.65f)){
|
||||
|
||||
float dst = 999f;
|
||||
|
||||
Object[] sectors = Planets.serpulo.sectors.items;
|
||||
int size = Planets.serpulo.sectors.size;
|
||||
|
||||
for(int i = 0; i < size; i ++){
|
||||
var sector = (Sector)sectors[i];
|
||||
|
||||
if(sector.hasEnemyBase()){
|
||||
dst = Math.min(dst, position.dst(sector.tile.v));
|
||||
}
|
||||
}
|
||||
|
||||
float freq = 0.05f, freq2 = 0.07f;
|
||||
|
||||
if(dst*0.85f + Simplex.noise3d(seed, 3, 0.4, 5.5f, position.x, position.y + 200f, position.z)*0.015f + ((basePos.dst(position) + 0.00f) % freq < freq/2f ? 1f : 0f) * 0.07f < 0.15f){
|
||||
return ((basePos.dst(position) + 0.01f) % freq2 < freq2*0.65f) ? Blocks.metalFloor : Blocks.darkPanel6;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -156,7 +243,7 @@ public class SerpuloPlanetGenerator extends PlanetGenerator{
|
||||
Vec2 midpoint = Tmp.v1.set(to.x, to.y).add(x, y).scl(0.5f);
|
||||
rand.nextFloat();
|
||||
|
||||
if(alt){
|
||||
if(indirectPaths){
|
||||
midpoint.add(Tmp.v2.set(1, 0f).setAngle(Angles.angle(to.x, to.y, x, y) + 90f * (rand.chance(0.5) ? 1f : -1f)).scl(Tmp.v1.dst(x, y) * 2f));
|
||||
}else{
|
||||
//add randomized offset to avoid straight lines
|
||||
|
||||
@@ -14,7 +14,7 @@ import mindustry.world.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class TantrosPlanetGenerator extends PlanetGenerator{
|
||||
Color c1 = Color.valueOf("5057a6"), c2 = Color.valueOf("272766"), out = new Color();
|
||||
Color c1 = Color.valueOf("5057a6"), c2 = Color.valueOf("272766");
|
||||
|
||||
Block[][] arr = {
|
||||
{Blocks.redmat, Blocks.redmat, Blocks.darksand, Blocks.bluemat, Blocks.bluemat}
|
||||
@@ -30,9 +30,9 @@ public class TantrosPlanetGenerator extends PlanetGenerator{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor(Vec3 position){
|
||||
public void getColor(Vec3 position, Color out){
|
||||
float depth = Simplex.noise3d(seed, 2, 0.56, 1.7f, position.x, position.y, position.z) / 2f;
|
||||
return c1.write(out).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(0.2f);
|
||||
out.set(c1).lerp(c2, Mathf.clamp(Mathf.round(depth, 0.15f))).a(1f - 0.2f).toFloatBits();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -413,11 +413,22 @@ public class Mods implements Loadable{
|
||||
|
||||
/** Removes a mod file and marks it for requiring a restart. */
|
||||
public void removeMod(LoadedMod mod){
|
||||
if(!android && mod.loader != null){
|
||||
try{
|
||||
ClassLoaderCloser.close(mod.loader);
|
||||
}catch(Exception e){
|
||||
Log.err(e);
|
||||
boolean deleted = true;
|
||||
|
||||
if(mod.loader != null){
|
||||
if(android){
|
||||
//Try to remove cache for Android 14 security problem
|
||||
Fi cacheDir = new Fi(Core.files.getCachePath()).child("mods");
|
||||
Fi modCacheDir = cacheDir.child(mod.file.nameWithoutExtension());
|
||||
if(modCacheDir.exists()){
|
||||
deleted = modCacheDir.deleteDirectory();
|
||||
}
|
||||
}else{
|
||||
try{
|
||||
ClassLoaderCloser.close(mod.loader);
|
||||
}catch(Exception e){
|
||||
Log.err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +436,7 @@ public class Mods implements Loadable{
|
||||
mod.root.delete();
|
||||
}
|
||||
|
||||
boolean deleted = mod.file.isDirectory() ? mod.file.deleteDirectory() : mod.file.delete();
|
||||
deleted &= mod.file.isDirectory() ? mod.file.deleteDirectory() : mod.file.delete();
|
||||
|
||||
if(!deleted){
|
||||
ui.showErrorMessage("@mod.delete.error");
|
||||
@@ -1112,6 +1123,11 @@ public class Mods implements Loadable{
|
||||
//close the classloader for jar mods
|
||||
if(!android){
|
||||
ClassLoaderCloser.close(other.loader);
|
||||
}else if(other.loader != null){
|
||||
//Try to remove cache for Android 14 security problem
|
||||
Fi cacheDir = new Fi(Core.files.getCachePath()).child("mods");
|
||||
Fi modCacheDir = cacheDir.child(other.file.nameWithoutExtension());
|
||||
modCacheDir.deleteDirectory();
|
||||
}
|
||||
|
||||
//close zip file
|
||||
|
||||
@@ -91,6 +91,10 @@ public class Administration{
|
||||
dosBlacklist.add(address);
|
||||
}
|
||||
|
||||
public synchronized void unBlacklistDos(String address){
|
||||
dosBlacklist.remove(address);
|
||||
}
|
||||
|
||||
public synchronized boolean isDosBlacklisted(String address){
|
||||
return dosBlacklist.contains(address);
|
||||
}
|
||||
|
||||
@@ -113,6 +113,8 @@ public class ArcNetProvider implements NetProvider{
|
||||
|
||||
//kill connections above the limit to prevent spam
|
||||
if((playerLimitCache > 0 && server.getConnections().length > playerLimitCache) || netServer.admins.isDosBlacklisted(ip)){
|
||||
Log.info("Closing connection @ - IP marked as a potential DOS attack.", ip);
|
||||
|
||||
connection.close(DcReason.closed);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ public class CrashHandler{
|
||||
report += "Report this at " + Vars.reportIssueURL + "\n\n";
|
||||
}
|
||||
|
||||
var enabledMods = mods == null ? null : mods.list().select(m -> m.shouldBeEnabled() && m.isSupported());
|
||||
|
||||
return report
|
||||
+ "Version: " + Version.combined() + (Version.buildDate.equals("unknown") ? "" : " (Built " + Version.buildDate + ")") + (Vars.headless ? " (Server)" : "") + "\n"
|
||||
+ "Date: " + new SimpleDateFormat("MMMM d, yyyy HH:mm:ss a", Locale.getDefault()).format(new Date()) + "\n"
|
||||
@@ -37,7 +39,7 @@ public class CrashHandler{
|
||||
+ "Runtime Available Memory: " + (Runtime.getRuntime().maxMemory() / 1024 / 1024) + "mb\n"
|
||||
+ "Cores: " + OS.cores + "\n"
|
||||
+ (cause == null ? "" : "Likely Cause: " + cause.meta.displayName + " (" + cause.name + " v" + cause.meta.version + ")\n")
|
||||
+ (mods == null ? "<no mod init>" : "Mods: " + (!mods.list().contains(LoadedMod::shouldBeEnabled) ? "none (vanilla)" : mods.list().select(LoadedMod::shouldBeEnabled).toString(", ", mod -> mod.name + ":" + mod.meta.version)))
|
||||
+ (enabledMods == null ? "<no mod init>" : "Mods: " + (enabledMods.isEmpty() ? "none (vanilla)" : enabledMods.toString(", ", mod -> mod.name + ":" + mod.meta.version)))
|
||||
+ "\n\n" + error;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public enum Achievement{
|
||||
|
||||
have10mItems(SStat.totalCampaignItems, 10_000_000),
|
||||
killEclipseDuo,
|
||||
killMassDriver,
|
||||
|
||||
completeErekir,
|
||||
completeSerpulo,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user