Compare commits

...

31 Commits

Author SHA1 Message Date
Anuken
3b8f789955 Merge remote-tracking branch 'origin/master' 2023-05-11 15:24:45 -04:00
Anuken
be751f5b28 Minor cleanup 2023-05-11 15:24:41 -04:00
Github Actions
9a7f8bb573 Automatic bundle update 2023-05-11 17:42:50 +00:00
Anuken
d34631458e Mobile rebuild button support 2023-05-11 13:41:45 -04:00
Anuken
74f1688dd2 Merge remote-tracking branch 'origin/master' 2023-05-11 12:52:37 -04:00
Anuken
9745c2b7fd Better utilization of JoinDialog UI space 2023-05-11 12:52:32 -04:00
Phinner
bedd8f612a Update French translation (#8579)
* pull #7883

* add new translations

* add these fine gentlemen to the contributors

* bateau -> vaisseau

* forgor again 💀

* chore: Translate missing strings + Small changes

* chore: Apply suggested changes (author: Kalpas)
2023-05-11 12:04:14 -04:00
Anuken
38de095a2e Fixed map alignment 2023-05-11 11:59:45 -04:00
Anuken
8c56568f23 Reverted name change to un-break mods 2023-05-11 11:51:57 -04:00
Anuken
d14c42d8ba Disabled annoying X scrolling in map dialogs 2023-05-11 11:39:49 -04:00
Anuken
bed0bd135e Merge remote-tracking branch 'origin/master' 2023-05-11 11:24:47 -04:00
Anuken
b3e111ebbb Merged Custom/editor maps implementation 2023-05-11 11:24:42 -04:00
MEEPofFaith
2c77477987 PartMove progress is ignored for growth (#8580) 2023-05-11 01:06:49 -04:00
MEEPofFaith
397fd087f2 RegionPart movement should not be affected by growth scale (#8578) 2023-05-10 21:07:40 -04:00
Phinner
0919063ca3 Add BlockRotateEvent (#8577)
* feat: Add BuildRotateEvent

* fix: Fix invalid argument

* fix: Goofy aaah static imports

* chore: Update ConfigEvent doc + Add forgotten annotation

* chore: Remove final keyword

* fix: Remove rotation validation in Build#beginPlace

* Already covered by client snapshots

* fix: Remove useless imports
2023-05-10 21:03:08 -04:00
Anuken
51daa82a1b Fixed JSON sector preset files failing to load 2023-05-10 15:57:43 -04:00
Anuken
e60fff43bd Minor DrawPistons fix 2023-05-10 13:13:43 -04:00
MEEPofFaith
a5eda4fb2e Horizontal shifting of pistons (also adds proper icons for pistons) (#8345)
* Horizontal offset for pistons

* might as well fix icons in the meantime

* Make a positive offset shift to the right
2023-05-10 13:10:48 -04:00
Anuken
c7ad9d0250 Cleanup 2023-05-10 13:05:49 -04:00
Anuken
c5cf6f0af6 Cleanup 2023-05-10 13:00:49 -04:00
xStaBUx
a3dbbe63c4 Better planet selection (#8572)
* Better AboutDialog

* I'm there!

* New Planet Select UI

* fix

* Better Planet Selection

* no
2023-05-10 12:54:18 -04:00
MEEPofFaith
31bed37976 Ser-pew-lo Turret Animations (#8562)
* Scatter animations

* Do the same thing to salvo

Like, the exact same thing.

Corporate wants you to tell the difference between these two pictures.
They're the same picture.

* Faster salvo barrel recoil

* Move entire scatter midsection

* Cyclone barrel animations
2023-05-10 12:52:54 -04:00
Даркнесс#3729
4f845202f8 sendUnformatted method in PlayerComp (#8575) 2023-05-10 12:52:47 -04:00
Anuken
cac29c4ecc Placeable overlays 2023-05-10 12:48:41 -04:00
Anuken
0acb112f29 Allow placing floors (for mods) 2023-05-10 12:37:25 -04:00
Anuken
778e7d5f3f Merge remote-tracking branch 'origin/master' 2023-05-10 11:54:44 -04:00
Anuken
1b254745e9 bigger numbers 2023-05-10 11:54:39 -04:00
MEEPofFaith
1373381554 Properly handle missile units shooting more missile units (#8359)
* Properly handle missile units shooting more missile units

* Remove `shooter`, just pass down the owner
2023-05-09 20:34:13 -04:00
MEEPofFaith
2289f29bd5 Revert Math.max in shakeReduction (#8570) 2023-05-09 09:33:59 -04:00
MEEPofFaith
552d6a2e9f Smoother Screenshake Reduction (#8310)
* Smoother Screenshake Reduction

Screen shake will now always reach 0 no matter the intensity or duration without being cut off early.

* Keep the max reduction rate
2023-05-08 18:41:56 -04:00
MEEPofFaith
9aa45b2a7c Attempt healing targetting even if the bullet doesn't collide with ground targets (#8516) 2023-05-08 17:05:27 -04:00
84 changed files with 750 additions and 603 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@@ -1789,7 +1789,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \uE827 [accent]Map[] in the \uE88C [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \uE827 [accent]Map[] in the \uE88C [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \uE844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \uE844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1757,6 +1757,7 @@ hint.launch = Калі рэсурсы сабраны, вы можаце [accent]
hint.launch.mobile = Калі рэсурсы сабраны, вы можаце [accentЗапусціць[] выбіраючы сектара якія знаходзяцца побач на \ue827 [accent]Карце[] ў \ue88c [accent]Меню[]. hint.launch.mobile = Калі рэсурсы сабраны, вы можаце [accentЗапусціць[] выбіраючы сектара якія знаходзяцца побач на \ue827 [accent]Карце[] ў \ue88c [accent]Меню[].
hint.schematicSelect = Утрымайце [accent][[F][] і працягніце каб выбраць блокі для капіявання і ўстаўкі.\n\n[accent][[Сярэдні Пстрык][] каб скапіяваць толькі адзін тып блоку. hint.schematicSelect = Утрымайце [accent][[F][] і працягніце каб выбраць блокі для капіявання і ўстаўкі.\n\n[accent][[Сярэдні Пстрык][] каб скапіяваць толькі адзін тып блоку.
hint.rebuildSelect = Утрымайце [accent][[B][] і працягніце каб выбраць блокі для разбудавання.\nГэта перабудуе іх аўтаматычна. hint.rebuildSelect = Утрымайце [accent][[B][] і працягніце каб выбраць блокі для разбудавання.\nГэта перабудуе іх аўтаматычна.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Утрымайце [accent][[Левы Ctrl][] калі правозіце канвееры каб аутаматычна згенераваць шлях. hint.conveyorPathfind = Утрымайце [accent][[Левы Ctrl][] калі правозіце канвееры каб аутаматычна згенераваць шлях.
hint.conveyorPathfind.mobile = Уключыце \ue844 [accent]дыяганальны рэжым[] і утрымлівайце і размяшчайце канвееры па аўтаматычна згенераванаму шляху. hint.conveyorPathfind.mobile = Уключыце \ue844 [accent]дыяганальны рэжым[] і утрымлівайце і размяшчайце канвееры па аўтаматычна згенераванаму шляху.
hint.boost = Утрымайце [accent][[Левы Shift][] каб ляцець праз перашкоды з вашай выбранай адзінкай.\n\nТолькі некаторыя наземныя адзінкі могуць узлятаць. hint.boost = Утрымайце [accent][[Левы Shift][] каб ляцець праз перашкоды з вашай выбранай адзінкай.\n\nТолькі некаторыя наземныя адзінкі могуць узлятаць.

View File

@@ -1769,6 +1769,7 @@ hint.launch = След като съберете достатъчно ресур
hint.launch.mobile = След като съберете достатъчно ресурси, можете да [accent]Изстреляте[] ядро като изберете близък сектор от \ue827 [accent]Глобуса[] в \ue88c [accent]Менюто[]. hint.launch.mobile = След като съберете достатъчно ресурси, можете да [accent]Изстреляте[] ядро като изберете близък сектор от \ue827 [accent]Глобуса[] в \ue88c [accent]Менюто[].
hint.schematicSelect = Задръжте [accent][[F][] и плъзнете за да изберете/копирате група от блокчета.\n\n[accent][[Среден клик][] за да копирате едно блокче. hint.schematicSelect = Задръжте [accent][[F][] и плъзнете за да изберете/копирате група от блокчета.\n\n[accent][[Среден клик][] за да копирате едно блокче.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Задръжте [accent][[L-Ctrl][] докато поставяте пътека от конвейери за да генерирате пътека автоматично. hint.conveyorPathfind = Задръжте [accent][[L-Ctrl][] докато поставяте пътека от конвейери за да генерирате пътека автоматично.
hint.conveyorPathfind.mobile = Позволете \ue844 [accent]Диагонално Поставяне[] за автоматично намиране на пътека при поставяне на конвейери. hint.conveyorPathfind.mobile = Позволете \ue844 [accent]Диагонално Поставяне[] за автоматично намиране на пътека при поставяне на конвейери.
hint.boost = Задръжте [accent][[L-Shift][] за да прелетите над препятствия с тази единица.\n\nСамо някои наземни единици имат двигатели за летене. hint.boost = Задръжте [accent][[L-Shift][] за да прелетите над препятствия с тази единица.\n\nСамо някои наземни единици имат двигатели за летене.

View File

@@ -1779,6 +1779,7 @@ hint.launch = Un cop shan recollit prou recursos, podeu iniciar un llançamen
hint.launch.mobile = Un cop shan recollit prou recursos, podeu iniciar un llançament seleccionant un sector proper del \ue827 [accent]Mapa[] del \ue88c [accent]Menú[]. hint.launch.mobile = Un cop shan recollit prou recursos, podeu iniciar un llançament seleccionant un sector proper del \ue827 [accent]Mapa[] del \ue88c [accent]Menú[].
hint.schematicSelect = Manteniu premuda la tecla [accent]F[] i arrossegueu per a seleccionar els blocs que vulgueu copiar i enganxar.\n\nFeu clic amb el [accent]botó del mig[] del ratolí per a copiar només un tipus de bloc. hint.schematicSelect = Manteniu premuda la tecla [accent]F[] i arrossegueu per a seleccionar els blocs que vulgueu copiar i enganxar.\n\nFeu clic amb el [accent]botó del mig[] del ratolí per a copiar només un tipus de bloc.
hint.rebuildSelect = Manteniu premuda la tecla [accent][[B][] i arrossegueu per a seleccionar els plànols dels blocs destruïts.\nAixí, es podran reconstruir automàticament. hint.rebuildSelect = Manteniu premuda la tecla [accent][[B][] i arrossegueu per a seleccionar els plànols dels blocs destruïts.\nAixí, es podran reconstruir automàticament.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Manteniu premuda la tecla [accent]ControlEsquerra[] i arrossegueu les cintes per a generar un camí automàticament. hint.conveyorPathfind = Manteniu premuda la tecla [accent]ControlEsquerra[] i arrossegueu les cintes per a generar un camí automàticament.
hint.conveyorPathfind.mobile = Activeu el \ue844 [accent]mode diagonal[] i arrossegueu les cintes per a generar un camí automàticament. hint.conveyorPathfind.mobile = Activeu el \ue844 [accent]mode diagonal[] i arrossegueu les cintes per a generar un camí automàticament.
hint.boost = Manteniu premuda la tecla [accent]ControlEsquerra[] per a sobrevolar els obstacles amb la unitat actual.\n\nNomés algunes unitats terrestres tenen elevadors per a poder-ho fer. hint.boost = Manteniu premuda la tecla [accent]ControlEsquerra[] per a sobrevolar els obstacles amb la unitat actual.\n\nNomés algunes unitats terrestres tenen elevadors per a poder-ho fer.

View File

@@ -1773,6 +1773,7 @@ hint.launch = Jakmile je nasbíráno dostatek zdrojových materiálů, můžeš
hint.launch.mobile = Jakmile je nasbíráno dostatek zdrojových materiálů, můžeš se [accent]vyslat[] do přilehlých sektorů z \ue827 [accent]mapy[] v the \ue88c [accent]nabídce[]. hint.launch.mobile = Jakmile je nasbíráno dostatek zdrojových materiálů, můžeš se [accent]vyslat[] do přilehlých sektorů z \ue827 [accent]mapy[] v the \ue88c [accent]nabídce[].
hint.schematicSelect = Podrž [accent][[F][] a potáhni pro výběr bloků, které chceš zkopírovat.\n\nKlikni na [accent][[prostřední tlačítko][] myši pro zkopírování jednoho typu bloku. hint.schematicSelect = Podrž [accent][[F][] a potáhni pro výběr bloků, které chceš zkopírovat.\n\nKlikni na [accent][[prostřední tlačítko][] myši pro zkopírování jednoho typu bloku.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Podrž [accent][[levý Ctrl][], když táhneš dopravníky, pro automatické vygenerování cesty. hint.conveyorPathfind = Podrž [accent][[levý Ctrl][], když táhneš dopravníky, pro automatické vygenerování cesty.
hint.conveyorPathfind.mobile = Povol \ue844 [accent]úhlopříčný režim[] a potáhni dopravníky pro automatické generování cesty. hint.conveyorPathfind.mobile = Povol \ue844 [accent]úhlopříčný režim[] a potáhni dopravníky pro automatické generování cesty.
hint.boost = Podrž [accent][[levý Shift][], abys přeletěl přes překážky se svou současnou jednotkou.\n\nPouze některé jednotky však mají takový posilovač. hint.boost = Podrž [accent][[levý Shift][], abys přeletěl přes překážky se svou současnou jednotkou.\n\nPouze některé jednotky však mají takový posilovač.

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1789,6 +1789,7 @@ hint.launch = Sobald du genug Ressourcen gesammelt hast, kannst du [accent]Start
hint.launch.mobile = Sobald du genug Ressourcen gesammelt hast, kannst du [accent]Starten[], indem du andere Sektoren auf der \ue827 [accent]Karte[] im \ue88c [accent]Menü[] auswählst. hint.launch.mobile = Sobald du genug Ressourcen gesammelt hast, kannst du [accent]Starten[], indem du andere Sektoren auf der \ue827 [accent]Karte[] im \ue88c [accent]Menü[] auswählst.
hint.schematicSelect = Halte [accent][[F][] gedrückt und bewege deine Maus, um Blöcke zu kopieren.\n\nMit [accent][[Mittelklick][] kannst du einen einzelnen Block kopieren. hint.schematicSelect = Halte [accent][[F][] gedrückt und bewege deine Maus, um Blöcke zu kopieren.\n\nMit [accent][[Mittelklick][] kannst du einen einzelnen Block kopieren.
hint.rebuildSelect = Halte [accent][[B][] gedrückt und bewege deine Maus, um Überreste zerstörter Blöcke auszuwählen.\nDiese werden dann automatisch wiederaufgebaut. hint.rebuildSelect = Halte [accent][[B][] gedrückt und bewege deine Maus, um Überreste zerstörter Blöcke auszuwählen.\nDiese werden dann automatisch wiederaufgebaut.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Halte [accent][[L-STRG][] während du Förderbänder baust, um automatisch einen Weg zu finden. hint.conveyorPathfind = Halte [accent][[L-STRG][] während du Förderbänder baust, um automatisch einen Weg zu finden.
hint.conveyorPathfind.mobile = Aktiviere den \ue844 [accent]Diagonal-Modus[] unten rechts und platziere Förderbänder, um automatisch einen Weg zu generieren. hint.conveyorPathfind.mobile = Aktiviere den \ue844 [accent]Diagonal-Modus[] unten rechts und platziere Förderbänder, um automatisch einen Weg zu generieren.

View File

@@ -1785,6 +1785,7 @@ hint.launch = Cuando tengas sufientes recursos, puedes [accent]Lanzar el núcleo
hint.launch.mobile = Cuando tengas sufientes recursos, puedes [accent]Lanzar el núcleo[] escogiendo como objetivo sectores cercanos en el [accent]Mapa[], disponible desde el [accent]Menú de pausa[]. hint.launch.mobile = Cuando tengas sufientes recursos, puedes [accent]Lanzar el núcleo[] escogiendo como objetivo sectores cercanos en el [accent]Mapa[], disponible desde el [accent]Menú de pausa[].
hint.schematicSelect = Mantén [accent][[F][] y arrastra para crear una selección de bloques que puedes copiar y pegar.\n\nUsa [accent][[Clic central][] para seleccionar un tipo de bloque. hint.schematicSelect = Mantén [accent][[F][] y arrastra para crear una selección de bloques que puedes copiar y pegar.\n\nUsa [accent][[Clic central][] para seleccionar un tipo de bloque.
hint.rebuildSelect = Mantén [accent][[B][] y arrastra para seleccionar planos de bloques destruidos.\nEsto los reconstruirá automáticamente. hint.rebuildSelect = Mantén [accent][[B][] y arrastra para seleccionar planos de bloques destruidos.\nEsto los reconstruirá automáticamente.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Mantener [accent][[L-Ctrl][] mientras arrastras cintas transportadoras generará automáticamente una ruta. hint.conveyorPathfind = Mantener [accent][[L-Ctrl][] mientras arrastras cintas transportadoras generará automáticamente una ruta.
hint.conveyorPathfind.mobile = Activa el [accent]modo diagonal[] y arrastra cintas transportadoras para generar una ruta inteligente. hint.conveyorPathfind.mobile = Activa el [accent]modo diagonal[] y arrastra cintas transportadoras para generar una ruta inteligente.
hint.boost = Mantén [accent][[L-Shift][] para sobrevolar obstáculos con tu unidad actual.\n\nSólo algunas unidades terrestres disponen de propulsores que les otorgan esta habilidad. hint.boost = Mantén [accent][[L-Shift][] para sobrevolar obstáculos con tu unidad actual.\n\nSólo algunas unidades terrestres disponen de propulsores que les otorgan esta habilidad.

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1760,6 +1760,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1760,6 +1760,7 @@ hint.launch = Kun olet kerännyt riittävästi resursseja, voit [accent]Laukaist
hint.launch.mobile = Kun olet kerännyt riittävästi resursseja, voit [accent]Laukaista[] valitsemalla läheisen sektorin \ue827[accent]Kartasta[], joka löytyy \ue88c[accent]Valikosta[]. hint.launch.mobile = Kun olet kerännyt riittävästi resursseja, voit [accent]Laukaista[] valitsemalla läheisen sektorin \ue827[accent]Kartasta[], joka löytyy \ue88c[accent]Valikosta[].
hint.schematicSelect = Pidä näppäintä [accent][[F][] pohjassa ja vedä valitaksesi palikoita kopioitavaksi ja liitettäväksi.\n\n[accent] Paina [[Hiiren keskinäppäin][] kopioidaksesi yksittäisen palikan. hint.schematicSelect = Pidä näppäintä [accent][[F][] pohjassa ja vedä valitaksesi palikoita kopioitavaksi ja liitettäväksi.\n\n[accent] Paina [[Hiiren keskinäppäin][] kopioidaksesi yksittäisen palikan.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Pidä näppäintä [accent][[Vasen ctrl][] pohjassa, kun vedät liukuhihnoja luodaksesi polun automaattisesti. hint.conveyorPathfind = Pidä näppäintä [accent][[Vasen ctrl][] pohjassa, kun vedät liukuhihnoja luodaksesi polun automaattisesti.
hint.conveyorPathfind.mobile = Salli \ue844[accent]Viisto tila[] ja vedä liukuhihnoja luodaksesi polun automaattisesti. hint.conveyorPathfind.mobile = Salli \ue844[accent]Viisto tila[] ja vedä liukuhihnoja luodaksesi polun automaattisesti.
hint.boost = Pidä [accent][[Vasen shift][] pohjassa lentääksesi esteiden yli yksikölläsi.\n\nVain harvoilla maajoukoilla on tehostin. hint.boost = Pidä [accent][[Vasen shift][] pohjassa lentääksesi esteiden yli yksikölläsi.\n\nVain harvoilla maajoukoilla on tehostin.

View File

@@ -1757,6 +1757,7 @@ hint.launch = Kapag sapat na ang mga mapagkukunan, maaari mong [accent]Ilunsad[]
hint.launch.mobile = Kapag sapat na ang mga mapagkukunan, maaari mong [accent]Ilunsad[] sa pamamagitan ng pagpili sa mga kalapit na sektor mula sa \ue827 [accent]Map[] sa \ue88c [accent]Menu[]. hint.launch.mobile = Kapag sapat na ang mga mapagkukunan, maaari mong [accent]Ilunsad[] sa pamamagitan ng pagpili sa mga kalapit na sektor mula sa \ue827 [accent]Map[] sa \ue88c [accent]Menu[].
hint.schematicSelect = Pindutin ang [accent][[F][] at i-drag upang pumili ng mga bloke na kokopyahin at ipe-paste.\n\n[accent][[Middle Click][] upang kopyahin ang isang uri ng block. hint.schematicSelect = Pindutin ang [accent][[F][] at i-drag upang pumili ng mga bloke na kokopyahin at ipe-paste.\n\n[accent][[Middle Click][] upang kopyahin ang isang uri ng block.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Pindutin ang [accent][[L-Ctrl][] habang dina-drag ang mga conveyor para awtomatikong bumuo ng landas. hint.conveyorPathfind.mobile = Pindutin ang [accent][[L-Ctrl][] habang dina-drag ang mga conveyor para awtomatikong bumuo ng landas.
hint.boost = Pindutin ang [accent][[L-Shift][] para lumipad sa mga obstacle kasama ang iyong kasalukuyang unit.\n\nIlang ground unit lang ang may mga booster hint.boost = Pindutin ang [accent][[L-Shift][] para lumipad sa mga obstacle kasama ang iyong kasalukuyang unit.\n\nIlang ground unit lang ang may mga booster

View File

@@ -150,16 +150,16 @@ mod.incompatiblemod = [red]Incompatible
mod.blacklisted = [red]Non supporté mod.blacklisted = [red]Non supporté
mod.unmetdependencies = [red]Dépendances manquantes mod.unmetdependencies = [red]Dépendances manquantes
mod.erroredcontent = [scarlet]Erreurs dans le contenu ! mod.erroredcontent = [scarlet]Erreurs dans le contenu !
mod.circulardependencies = [red]Circular Dependencies mod.circulardependencies = [red]pendances circulaires
mod.incompletedependencies = [red]Incomplete Dependencies mod.incompletedependencies = [red]Dépendances incomplètes
mod.requiresversion.details = Requiert la version: [accent]{0}[]\nVotre jeu n'est pas à jour. Ce mod a besoin d'une version récente du jeu (la beta ou l'alpha) pour fonctionner. mod.requiresversion.details = Requiert la version: [accent]{0}[]\nVotre jeu n'est pas à jour. Ce mod a besoin d'une version récente du jeu (la beta ou l'alpha) pour fonctionner.
mod.outdatedv7.details = Ce mod est incompatible avec la version la plus récente du jeu. L'auteur doit le mettre à jour et ajouter [accent]minGameVersion: 136[] dans le fichier [accent]mod.json[]. mod.outdatedv7.details = Ce mod est incompatible avec la version la plus récente du jeu. L'auteur doit le mettre à jour et ajouter [accent]minGameVersion: 136[] dans le fichier [accent]mod.json[].
mod.blacklisted.details = Ce mod à été manuellement mis sur liste noire car il cause des crashs ou d'autres problèmes avec la version actuelle du jeu. Ne l'utilisez pas. mod.blacklisted.details = Ce mod à été mis sur liste noire, car il cause des plantages ou d'autres problèmes avec la version actuelle du jeu. Ne l'utilisez pas.
mod.missingdependencies.details = Ce mod à des dépendances manquantes: {0} mod.missingdependencies.details = Ce mod à des dépendances manquantes: {0}
mod.erroredcontent.details = Ce mod cause des erreurs lors du chargement. Demandez à l'autheur de les régler. mod.erroredcontent.details = Ce mod cause des erreurs lors du chargement. Demandez à l'auteur de les régler.
mod.circulardependencies.details = This mod has dependencies that depends on each other. mod.circulardependencies.details = Ce mod à des dépendances qui dépendent les unes des autres.
mod.incompletedependencies.details = This mod is unable to be loaded due to invalid or missing dependencies: {0}. mod.incompletedependencies.details = Ce mod ne peut pas être chargé en raison de dépendances invalides ou manquantes: {0}.
mod.requiresversion = Requiert la version: [red]{0} mod.requiresversion = Requiert la version: [red]{0}
@@ -296,7 +296,7 @@ server.invalidport = Numéro de port invalide !
server.error = [scarlet]Erreur lors de l'hébergement du serveur. server.error = [scarlet]Erreur lors de l'hébergement du serveur.
save.new = Nouvelle sauvegarde save.new = Nouvelle sauvegarde
save.overwrite = Êtes-vous sûr de vouloir\nécraser cette sauvegarde ? save.overwrite = Êtes-vous sûr de vouloir\nécraser cette sauvegarde ?
save.nocampaign = Individual save files from the campaign cannot be imported. save.nocampaign = Les fichiers de sauvegarde de la campagne ne peuvent pas être importés individuellement.
overwrite = Écraser overwrite = Écraser
save.none = Aucune sauvegarde trouvée ! save.none = Aucune sauvegarde trouvée !
savefail = Échec de la sauvegarde ! savefail = Échec de la sauvegarde !
@@ -339,7 +339,7 @@ command.repair = Réparer
command.rebuild = Reconstruire command.rebuild = Reconstruire
command.assist = Assister command.assist = Assister
command.move = Bouger command.move = Bouger
command.boost = Boost command.boost = Booster
openlink = Ouvrir le lien openlink = Ouvrir le lien
copylink = Copier le lien copylink = Copier le lien
back = Retour back = Retour
@@ -365,8 +365,8 @@ pausebuilding = [accent][[{0}][] pour mettre la construction en pause
resumebuilding = [scarlet][[{0}][] pour reprendre la construction resumebuilding = [scarlet][[{0}][] pour reprendre la construction
enablebuilding = [scarlet][[{0}][] pour activer la construction enablebuilding = [scarlet][[{0}][] pour activer la construction
showui = Interface cachée.\nPressez [accent][[{0}][] pour montrer l'interface. showui = Interface cachée.\nPressez [accent][[{0}][] pour montrer l'interface.
commandmode.name = [accent]Command Mode commandmode.name = [accent]Mode « Commande »
commandmode.nounits = [no units] commandmode.nounits = [aucune unité]
wave = [accent]Vague {0} wave = [accent]Vague {0}
wave.cap = [accent]Vague {0}/{1} wave.cap = [accent]Vague {0}/{1}
wave.waiting = [lightgray]Vague dans {0} wave.waiting = [lightgray]Vague dans {0}
@@ -451,7 +451,7 @@ waves.max = unités maximum
waves.guardian = Gardien waves.guardian = Gardien
waves.preview = Prévisualiser waves.preview = Prévisualiser
waves.edit = Modifier... waves.edit = Modifier...
waves.random = Random waves.random = Aléatoire
waves.copy = Copier dans le presse-papiers waves.copy = Copier dans le presse-papiers
waves.load = Coller depuis le presse-papiers waves.load = Coller depuis le presse-papiers
waves.invalid = Vagues invalides dans le presse-papiers. waves.invalid = Vagues invalides dans le presse-papiers.
@@ -462,8 +462,8 @@ waves.sort.reverse = Tri inversé
waves.sort.begin = Vague waves.sort.begin = Vague
waves.sort.health = Santé waves.sort.health = Santé
waves.sort.type = Type waves.sort.type = Type
waves.search = Search waves... waves.search = Rechercher des vagues...
waves.filter.unit = Unit Filter waves.filter.unit = Filtre d'Unité
waves.units.hide = Masquer tout waves.units.hide = Masquer tout
waves.units.show = Afficher tout waves.units.show = Afficher tout
@@ -488,7 +488,7 @@ editor.errornot = Ceci n'est pas un fichier de carte.
editor.errorheader = Ce fichier de carte est invalide ou corrompu. editor.errorheader = Ce fichier de carte est invalide ou corrompu.
editor.errorname = La carte n'a pas de nom. Essayez-vous de charger une sauvegarde ? editor.errorname = La carte n'a pas de nom. Essayez-vous de charger une sauvegarde ?
editor.update = Mettre à jour editor.update = Mettre à jour
editor.randomize = Randomiser editor.randomize = Générer
editor.moveup = Monter editor.moveup = Monter
editor.movedown = Descendre editor.movedown = Descendre
editor.copy = Copier editor.copy = Copier
@@ -902,7 +902,7 @@ stat.repairspeed = Vitesse de réparation
stat.weapons = Armes stat.weapons = Armes
stat.bullet = Balles stat.bullet = Balles
stat.moduletier = Tier stat.moduletier = Tier
stat.unittype = Unit Type stat.unittype = Type d'Unité
stat.speedincrease = Accélération stat.speedincrease = Accélération
stat.range = Portée stat.range = Portée
stat.drilltier = Blocs forables stat.drilltier = Blocs forables
@@ -914,7 +914,7 @@ stat.armor = Armure
stat.buildtime = Durée de construction stat.buildtime = Durée de construction
stat.maxconsecutive = Max Consécutif stat.maxconsecutive = Max Consécutif
stat.buildcost = Coût de construction stat.buildcost = Coût de construction
stat.inaccuracy = Précision stat.inaccuracy = Imprécision
stat.shots = Tirs stat.shots = Tirs
stat.reload = Cadence de tir stat.reload = Cadence de tir
stat.ammo = Munitions stat.ammo = Munitions
@@ -996,9 +996,9 @@ bullet.splashdamage = [stat]{0}[lightgray] dégâts de zone ~[stat] {1}[lightgra
bullet.incendiary = [stat]incendiaire bullet.incendiary = [stat]incendiaire
bullet.homing = [stat]autoguidé bullet.homing = [stat]autoguidé
bullet.armorpierce = [stat]perceur d'armure bullet.armorpierce = [stat]perceur d'armure
bullet.suppression = [stat]{0} sec[lightgray] repair suppression ~ [stat]{1}[lightgray] tiles bullet.suppression = [stat]{0} sec[lightgray] suppression de soins ~ [stat]{1}[lightgray] blocs
bullet.interval = [stat]{0}/sec[lightgray] interval bullets: bullet.interval = [stat]{0}/sec[lightgray] Balle secondaire:
bullet.frags = [stat]{0}[lightgray]x Balle à fragmentation : bullet.frags = [stat]{0}[lightgray]x Balle à fragmentation:
bullet.lightning = [stat]{0}[lightgray]x foudre ~ [stat]{1}[lightgray] dégâts bullet.lightning = [stat]{0}[lightgray]x foudre ~ [stat]{1}[lightgray] dégâts
bullet.buildingdamage = [stat]{0}%[lightgray] des dégâts aux bâtiments bullet.buildingdamage = [stat]{0}%[lightgray] des dégâts aux bâtiments
bullet.knockback = [stat]{0}[lightgray] recul bullet.knockback = [stat]{0}[lightgray] recul
@@ -1007,13 +1007,13 @@ bullet.infinitepierce = [stat]perçant
bullet.healpercent = [stat]{0}[lightgray]% soins bullet.healpercent = [stat]{0}[lightgray]% soins
bullet.healamount = [stat]{0}[lightgray] réparation directe bullet.healamount = [stat]{0}[lightgray] réparation directe
bullet.multiplier = [stat]{0}[lightgray]x multiplicateur de munitions bullet.multiplier = [stat]{0}[lightgray]x multiplicateur de munitions
bullet.reload = [stat]{0}[lightgray]x vitesse de tir bullet.reload = [stat]{0}[lightgray]% vitesse de tir
bullet.range = [stat]{0}[lightgray] tuiles de portée bullet.range = [stat]{0}[lightgray] blocs de portée
unit.blocks = blocs unit.blocks = blocs
unit.blockssquared = blocs² unit.blockssquared = blocs²
unit.powersecond = unités d'énergie/seconde unit.powersecond = unités d'énergie/seconde
unit.tilessecond = tuiles/seconde unit.tilessecond = blocs/seconde
unit.liquidsecond = unités de liquide/seconde unit.liquidsecond = unités de liquide/seconde
unit.itemssecond = objets/seconde unit.itemssecond = objets/seconde
unit.liquidunits = unités de liquide unit.liquidunits = unités de liquide
@@ -1111,8 +1111,8 @@ setting.bridgeopacity.name = Opacité des ponts
setting.playerchat.name = Montrer les bulles de discussion des joueurs setting.playerchat.name = Montrer les bulles de discussion des joueurs
setting.showweather.name = Montrer les Effets météo setting.showweather.name = Montrer les Effets météo
setting.hidedisplays.name = Cacher les Écrans setting.hidedisplays.name = Cacher les Écrans
steam.friendsonly = Friends Only steam.friendsonly = Amis seulement
steam.friendsonly.tooltip = Whether only Steam friends will be able to join your game.\nUnchecking this box will make your game public - anyone can join. steam.friendsonly.tooltip = Indique si seuls les amis Steam peuvent rejoindre votre partie.\nSi vous décochez cette case, votre partie deviendra publique et tout le monde pourra la rejoindre.
public.beta = Notez que les versions bêta du jeu ne peuvent pas créer de salons publics. public.beta = Notez que les versions bêta du jeu ne peuvent pas créer de salons publics.
uiscale.reset = L'échelle de l'interface a été modifiée.\nAppuyez sur "OK" pour confirmer.\n[scarlet]Rétablissement des anciens paramètres et fermeture du jeu dans [accent] {0}[] secondes... uiscale.reset = L'échelle de l'interface a été modifiée.\nAppuyez sur "OK" pour confirmer.\n[scarlet]Rétablissement des anciens paramètres et fermeture du jeu dans [accent] {0}[] secondes...
uiscale.cancel = Annuler & Quitter uiscale.cancel = Annuler & Quitter
@@ -1227,7 +1227,7 @@ rules.unitbuildspeedmultiplier = Multiplicateur de Vitesse de Construction des U
rules.unitcostmultiplier = Multiplicateur du coût de fabrication des Unités rules.unitcostmultiplier = Multiplicateur du coût de fabrication des Unités
rules.unithealthmultiplier = Multiplicateur de Santé des Unités rules.unithealthmultiplier = Multiplicateur de Santé des Unités
rules.unitdamagemultiplier = Multiplicateur de Dégât des Unités rules.unitdamagemultiplier = Multiplicateur de Dégât des Unités
rules.unitcrashdamagemultiplier = Unit Crash Damage Multiplier rules.unitcrashdamagemultiplier = Multiplicateur de Dégât de chute des Unités
rules.solarmultiplier = Multiplicateur de l'Efficacité des Panneaux Solaires rules.solarmultiplier = Multiplicateur de l'Efficacité des Panneaux Solaires
rules.unitcapvariable = Les Noyaux contribuent à la limite d'Unités actives rules.unitcapvariable = Les Noyaux contribuent à la limite d'Unités actives
rules.unitcap = Limite d'Unités actives de Base rules.unitcap = Limite d'Unités actives de Base
@@ -1239,8 +1239,8 @@ rules.buildcostmultiplier = Multiplicateur du prix de construction
rules.buildspeedmultiplier = Multiplicateur du temps de construction rules.buildspeedmultiplier = Multiplicateur du temps de construction
rules.deconstructrefundmultiplier = Multiplicateur du remboursement lors de la déconstruction rules.deconstructrefundmultiplier = Multiplicateur du remboursement lors de la déconstruction
rules.waitForWaveToEnd = Les Vagues attendent la mort des ennemis rules.waitForWaveToEnd = Les Vagues attendent la mort des ennemis
rules.wavelimit = Map Ends After Wave rules.wavelimit = La Partie termine après la Vague
rules.dropzoneradius = Rayon d'Apparition des ennemis :[lightgray] (tuiles) rules.dropzoneradius = Rayon d'Apparition des ennemis :[lightgray] (blocs)
rules.unitammo = Les Unités nécessitent des munitions rules.unitammo = Les Unités nécessitent des munitions
rules.enemyteam = Équipe ennemie rules.enemyteam = Équipe ennemie
rules.playerteam = Équipe du joueur rules.playerteam = Équipe du joueur
@@ -1587,9 +1587,9 @@ block.silicon-crucible.name = Grande Fonderie de Silicium
block.overdrive-dome.name = Dôme Accélérant block.overdrive-dome.name = Dôme Accélérant
block.interplanetary-accelerator.name = Accélérateur Interplanétaire block.interplanetary-accelerator.name = Accélérateur Interplanétaire
block.constructor.name = Constructeur block.constructor.name = Constructeur
block.constructor.description = Fabrique des structures d'une taille maximale de 2x2 (tuiles). block.constructor.description = Fabrique des structures d'une taille maximale de 2x2 (blocs).
block.large-constructor.name = Grand Constructeur block.large-constructor.name = Grand Constructeur
block.large-constructor.description = Fabrique des structures d'une taille maximale de 4x4 (tuiles). block.large-constructor.description = Fabrique des structures d'une taille maximale de 4x4 (blocs).
block.deconstructor.name = Déconstructeur block.deconstructor.name = Déconstructeur
block.deconstructor.description = Déconstruit les structures et les unités. Retourne 100% du coût de construction. block.deconstructor.description = Déconstruit les structures et les unités. Retourne 100% du coût de construction.
block.payload-loader.name = Chargeur de charge utile block.payload-loader.name = Chargeur de charge utile
@@ -1789,6 +1789,7 @@ hint.launch = Une fois que vous avez collecté assez de ressources, vous pouvez
hint.launch.mobile = Une fois que vous avez collecté assez de ressources, vous pouvez [accent]Lancer[] votre Noyau en sélectionnant un secteur depuis la \ue827 [accent]Carte[] dans le \ue88c [accent]Menu[]. hint.launch.mobile = Une fois que vous avez collecté assez de ressources, vous pouvez [accent]Lancer[] votre Noyau en sélectionnant un secteur depuis la \ue827 [accent]Carte[] dans le \ue88c [accent]Menu[].
hint.schematicSelect = Retenez [accent][[F][] pour sélectionner des blocs dans une zone afin de les copier et les coller.\n\n[accent][[Clic du milieu][] pour copier un seul type de bloc. hint.schematicSelect = Retenez [accent][[F][] pour sélectionner des blocs dans une zone afin de les copier et les coller.\n\n[accent][[Clic du milieu][] pour copier un seul type de bloc.
hint.rebuildSelect = Retenz [accent][[B][] et faites glissez pour selectionner les plans des blocs détruits.\nCela va automatiquement les reconstruire. hint.rebuildSelect = Retenz [accent][[B][] et faites glissez pour selectionner les plans des blocs détruits.\nCela va automatiquement les reconstruire.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Retenez [accent][[Ctrl-gauche][] pendant que vous placez des convoyeurs, afin de générer un chemin automatiquement. hint.conveyorPathfind = Retenez [accent][[Ctrl-gauche][] pendant que vous placez des convoyeurs, afin de générer un chemin automatiquement.
hint.conveyorPathfind.mobile = Activez le mode \ue844 [accent]Diagonale[] et déplacez des convoyeurs, afin de générer un chemin automatiquement. hint.conveyorPathfind.mobile = Activez le mode \ue844 [accent]Diagonale[] et déplacez des convoyeurs, afin de générer un chemin automatiquement.
@@ -2239,7 +2240,7 @@ lst.flushmessage = Affiche un message sur l'écran depuis la mémoire tampon de
lst.cutscene = Manipule la caméra du joueur. lst.cutscene = Manipule la caméra du joueur.
lst.setflag = Définit un drapeau global qui peut être lu par tous les processeurs. lst.setflag = Définit un drapeau global qui peut être lu par tous les processeurs.
lst.getflag = Vérifie si un drapeau global est présent. lst.getflag = Vérifie si un drapeau global est présent.
lst.setprop = Sets a property of a unit or building. lst.setprop = Change une propriété d'une unité ou d'un bâtiment.
logic.nounitbuild = [red]Les unités contrôlées par des processeurs ne peuvent pas construire ici. logic.nounitbuild = [red]Les unités contrôlées par des processeurs ne peuvent pas construire ici.
@@ -2254,7 +2255,7 @@ laccess.controller = Le contrôleur de l'Unité.\nSi l'Unité est contrôlée pa
laccess.dead = Retourne si l'Unité/Bâtiment est morte/détruit ou plus valide. laccess.dead = Retourne si l'Unité/Bâtiment est morte/détruit ou plus valide.
laccess.controlled = Retourne:\n[accent]@ctrlProcessor[] si le contrôleur de l'Unité est un processeur\n[accent]@ctrlPlayer[] si l'Unité/Bâtiment est contrôlé par un joueur\n[accent]@ctrlFormation[] si l'Unité est en formation\nSinon, retourne 0. laccess.controlled = Retourne:\n[accent]@ctrlProcessor[] si le contrôleur de l'Unité est un processeur\n[accent]@ctrlPlayer[] si l'Unité/Bâtiment est contrôlé par un joueur\n[accent]@ctrlFormation[] si l'Unité est en formation\nSinon, retourne 0.
laccess.progress = Progression de l'action, 0 à 1.\nRenvoie la progression de la production, du rechargement de la tourelle ou de la construction. laccess.progress = Progression de l'action, 0 à 1.\nRenvoie la progression de la production, du rechargement de la tourelle ou de la construction.
laccess.speed = La vitesse maximale d'une unité, en tuiles/sec. laccess.speed = La vitesse maximale d'une unité, en blocs/sec.
lcategory.unknown = Inconnu lcategory.unknown = Inconnu
lcategory.unknown.description = Instructions sans catégorie. lcategory.unknown.description = Instructions sans catégorie.

View File

@@ -1768,6 +1768,7 @@ hint.launch = Ha elegendő nyersanyagot gyűjtöttél, [accent]Kilőhetsz[] egy
hint.launch.mobile = Ha elegendő nyersanyagot gyűjtöttél, [accent]Kilőhetsz[] egy közeli szektorba. Ezt a \ue88c [accent]Menü[]ből elérhető \ue827 [accent]Térkép[]en teheted meg. hint.launch.mobile = Ha elegendő nyersanyagot gyűjtöttél, [accent]Kilőhetsz[] egy közeli szektorba. Ezt a \ue88c [accent]Menü[]ből elérhető \ue827 [accent]Térkép[]en teheted meg.
hint.schematicSelect = Az [accent][[F][] nyomva tartásával kijelölhetsz és másolhastz épületeket.\n\nKattints a [accent][[görgővel][], hogy egy épületet lemásolj. hint.schematicSelect = Az [accent][[F][] nyomva tartásával kijelölhetsz és másolhastz épületeket.\n\nKattints a [accent][[görgővel][], hogy egy épületet lemásolj.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Tartsd nyomva a [accent][[L-Ctrl][] billentyűt futószalagok lerakása közben, hogy a játék útvnalat generáljon. hint.conveyorPathfind = Tartsd nyomva a [accent][[L-Ctrl][] billentyűt futószalagok lerakása közben, hogy a játék útvnalat generáljon.
hint.conveyorPathfind.mobile = Enegdélyezd az \ue844 [accent]átlós mód[]ot és tagyél le egyszerre több futószalagot, hogy a játék útvonalat generáljon. hint.conveyorPathfind.mobile = Enegdélyezd az \ue844 [accent]átlós mód[]ot és tagyél le egyszerre több futószalagot, hogy a játék útvonalat generáljon.
hint.boost = Tartsd nyomva a [accent][[L-Shift][] billentyűt, hogy átrepülj az akadályok felett.\n\nErre nem minden földi egység képes. hint.boost = Tartsd nyomva a [accent][[L-Shift][] billentyűt, hogy átrepülj az akadályok felett.\n\nErre nem minden földi egység képes.

View File

@@ -1785,6 +1785,7 @@ hint.launch = Ketika sumber daya sudah mencukupi, kamu bisa [accent]Meluncurkan[
hint.launch.mobile = Ketika sumber daya sudah mencukupi, kamu bisa [accent]Meluncurkan[] dengan memilih sektor terdekat dari \ue827 [accent]Map[] di \ue88c [accent]Menu[]. hint.launch.mobile = Ketika sumber daya sudah mencukupi, kamu bisa [accent]Meluncurkan[] dengan memilih sektor terdekat dari \ue827 [accent]Map[] di \ue88c [accent]Menu[].
hint.schematicSelect = Tahan [accent][[F][] dan tarik ke bangunan untuk menyalin bangunan.\n\n[accent][[Klik tengah][] untuk menyalin blok setipe. hint.schematicSelect = Tahan [accent][[F][] dan tarik ke bangunan untuk menyalin bangunan.\n\n[accent][[Klik tengah][] untuk menyalin blok setipe.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Tahan [accent][[L-Ctrl][] ketika menarik pengantar untuk membuat jalur secara otomatis. hint.conveyorPathfind = Tahan [accent][[L-Ctrl][] ketika menarik pengantar untuk membuat jalur secara otomatis.
hint.conveyorPathfind.mobile = Aktifkan \ue844 [accent]diagonal mode[] dan tarik pengantar untuk membuat jalur secara otomatis. hint.conveyorPathfind.mobile = Aktifkan \ue844 [accent]diagonal mode[] dan tarik pengantar untuk membuat jalur secara otomatis.
hint.boost = Tahan [accent][[L-Shift][] untuk terbang dengan unit sekarang.\n\nHanya beberapa unit darat yang memiliki pendorong. hint.boost = Tahan [accent][[L-Shift][] untuk terbang dengan unit sekarang.\n\nHanya beberapa unit darat yang memiliki pendorong.

View File

@@ -1770,6 +1770,7 @@ hint.launch = Una volta che sono state raccolte abbastanza risorse, puoi[accent]
hint.launch.mobile = Una volta che sono state raccolte abbastanza risorse, puoi[accent]Lanciare[] selezionando settori vicini dalla \ue827 [accent]Mappa[] nel \ue88c [accent]menu[]. hint.launch.mobile = Una volta che sono state raccolte abbastanza risorse, puoi[accent]Lanciare[] selezionando settori vicini dalla \ue827 [accent]Mappa[] nel \ue88c [accent]menu[].
hint.schematicSelect = Tieni premuto [accent][[F][] e trascina per selezionare blocchi da copiare ed incollare.\n\n[accent][[Middle Click][] per copiare un singolo tipo di blocco. hint.schematicSelect = Tieni premuto [accent][[F][] e trascina per selezionare blocchi da copiare ed incollare.\n\n[accent][[Middle Click][] per copiare un singolo tipo di blocco.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Tieni premuto [accent][[L-Ctrl][] mentre trascini nastri per generare automaticamente un percorso. hint.conveyorPathfind = Tieni premuto [accent][[L-Ctrl][] mentre trascini nastri per generare automaticamente un percorso.
hint.conveyorPathfind.mobile = Attiva la \ue844 [accent]modalità diagonale[] e trascina nastri per generare automaticamente un percorso. hint.conveyorPathfind.mobile = Attiva la \ue844 [accent]modalità diagonale[] e trascina nastri per generare automaticamente un percorso.
hint.boost = Tieni premuto [accent][[L-Shift][] per volare sopra gli ostacoli con la tua unità attuale.\n\nSolo poche unità terrestri possono farlo. hint.boost = Tieni premuto [accent][[L-Shift][] per volare sopra gli ostacoli con la tua unità attuale.\n\nSolo poche unità terrestri possono farlo.

View File

@@ -1773,6 +1773,7 @@ hint.launch = 十分な資源を確保できたら、右下の\ue827 [accent]マ
hint.launch.mobile = 十分な資源を確保できたら、\ue88c [accent]メニュー[]の\ue827 [accent]マップ[]から、近くのセクターを選択して[accent]発射[]できます。 hint.launch.mobile = 十分な資源を確保できたら、\ue88c [accent]メニュー[]の\ue827 [accent]マップ[]から、近くのセクターを選択して[accent]発射[]できます。
hint.schematicSelect = [accent][[F][]を押しながらドラッグして、コピー&ペーストするブロックを選択します。\n\n[accent][[ミドルクリック][]により、1つのブロックタイプをコピーします。 hint.schematicSelect = [accent][[F][]を押しながらドラッグして、コピー&ペーストするブロックを選択します。\n\n[accent][[ミドルクリック][]により、1つのブロックタイプをコピーします。
hint.rebuildSelect = [accent][[B][] を押したままドラッグして、破壊されたブロック計画を選択します。\nこれにより、それらが自動的に再建築されます。 hint.rebuildSelect = [accent][[B][] を押したままドラッグして、破壊されたブロック計画を選択します。\nこれにより、それらが自動的に再建築されます。
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = [accent][[左-Ctrl][]を押しながらコンベアーをドラッグすると、経路が自動生成されます。 hint.conveyorPathfind = [accent][[左-Ctrl][]を押しながらコンベアーをドラッグすると、経路が自動生成されます。
hint.conveyorPathfind.mobile = \ue844 [accent]対角線モード[]を有効にし、コンベアーをドラッグすると経路が自動生成します。 hint.conveyorPathfind.mobile = \ue844 [accent]対角線モード[]を有効にし、コンベアーをドラッグすると経路が自動生成します。
hint.boost = [accent][[左シフト][]を押したままにすると、操作中のユニットは障害物を飛び越えます。\n\n少数の地上ユニットのみがこのブースターを搭載しています。 hint.boost = [accent][[左シフト][]を押したままにすると、操作中のユニットは障害物を飛び越えます。\n\n少数の地上ユニットのみがこのブースターを搭載しています。

View File

@@ -1772,6 +1772,7 @@ hint.launch = 충분한 자원을 모았으면, 오른쪽 아래의 \ue827 [acce
hint.launch.mobile = 충분한 자원을 모았으면, 오른쪽 아래의 \ue88c [accent]메뉴[]에 있는 \ue827 [accent]지도[]에서 주변 지역을 선택해서 [accent]출격[]할 수 있습니다. hint.launch.mobile = 충분한 자원을 모았으면, 오른쪽 아래의 \ue88c [accent]메뉴[]에 있는 \ue827 [accent]지도[]에서 주변 지역을 선택해서 [accent]출격[]할 수 있습니다.
hint.schematicSelect = [accent][[F][]를 누른 채로 끌어서 복사하고 붙여넣을 블록을 선택하십시오. \n\n [accent][[마우스 휠][]을 누르면 한 개의 블록만 복사할 수 있습니다. hint.schematicSelect = [accent][[F][]를 누른 채로 끌어서 복사하고 붙여넣을 블록을 선택하십시오. \n\n [accent][[마우스 휠][]을 누르면 한 개의 블록만 복사할 수 있습니다.
hint.rebuildSelect = [accent][[B][]를 누르고 끌어서 파괴된 블록 흔적을 선택하세요.\n선택된 블록은 자동으로 복구됩니다. hint.rebuildSelect = [accent][[B][]를 누르고 끌어서 파괴된 블록 흔적을 선택하세요.\n선택된 블록은 자동으로 복구됩니다.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = [accent][[왼쪽 Ctrl][]을 누른 채로 컨베이어를 대각선으로 끌면 길을 자동으로 만들어줍니다. hint.conveyorPathfind = [accent][[왼쪽 Ctrl][]을 누른 채로 컨베이어를 대각선으로 끌면 길을 자동으로 만들어줍니다.
hint.conveyorPathfind.mobile = \ue844 [accent]대각 모드[]를 활성화하고 컨베이어를 대각선으로 끌면 길을 자동으로 찾아줍니다. hint.conveyorPathfind.mobile = \ue844 [accent]대각 모드[]를 활성화하고 컨베이어를 대각선으로 끌면 길을 자동으로 찾아줍니다.
hint.boost = [accent][[왼쪽 Shift][]를 눌러 탑승한 기체로 장애물을 넘을 수 있습니다. \n\n 일부 지상 기체만 이륙할 수 있습니다. hint.boost = [accent][[왼쪽 Shift][]를 눌러 탑승한 기체로 장애물을 넘을 수 있습니다. \n\n 일부 지상 기체만 이륙할 수 있습니다.

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1771,6 +1771,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1779,6 +1779,7 @@ hint.launch = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrze
hint.launch.mobile = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] do pobliskich sektorów klikając w \ue827 [accent]Mapę[] w \ue88c [accent]Menu[]. hint.launch.mobile = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] do pobliskich sektorów klikając w \ue827 [accent]Mapę[] w \ue88c [accent]Menu[].
hint.schematicSelect = Przytrzymaj [accent][[F][] by kopiować i wkleić bloki.\n\n[accent][[Środkowy przycisk myszy][] kopiuje pojedynczy blok. hint.schematicSelect = Przytrzymaj [accent][[F][] by kopiować i wkleić bloki.\n\n[accent][[Środkowy przycisk myszy][] kopiuje pojedynczy blok.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Przeciągij i przytrzymaj [accent][[Lewy CTRL][] w trakcie budowania przenośników aby wygenerować ścieżkę. hint.conveyorPathfind = Przeciągij i przytrzymaj [accent][[Lewy CTRL][] w trakcie budowania przenośników aby wygenerować ścieżkę.
hint.conveyorPathfind.mobile = Włącz \ue844 [accent]tryb ukośny[] i przeciągnij w trakcie budowania przenośników aby wygenerować ścieżkę. hint.conveyorPathfind.mobile = Włącz \ue844 [accent]tryb ukośny[] i przeciągnij w trakcie budowania przenośników aby wygenerować ścieżkę.
hint.boost = Przytrzymaj [accent][[Lewy Shift][] by przelecieć ponad przeszkody.\n\nTylko część jednostek lądowych może to zrobić. hint.boost = Przytrzymaj [accent][[Lewy Shift][] by przelecieć ponad przeszkody.\n\nTylko część jednostek lądowych może to zrobić.

View File

@@ -1780,6 +1780,7 @@ hint.launch = Quando recursos suficientes forem coletados, você pode [accent]La
hint.launch.mobile = Quando recursos suficientes forem coletados, você pode [accent]Lançar[] selecionando setores próximos a partir do \ue827 [accent]Mapa[] no \ue88c [accent]Menu[]. hint.launch.mobile = Quando recursos suficientes forem coletados, você pode [accent]Lançar[] selecionando setores próximos a partir do \ue827 [accent]Mapa[] no \ue88c [accent]Menu[].
hint.schematicSelect = Segure [accent][[F][] e arraste para selecionar blocos para copiar e colar.\n\n[accent][[Middle Click][] para copiar um bloco só. hint.schematicSelect = Segure [accent][[F][] e arraste para selecionar blocos para copiar e colar.\n\n[accent][[Middle Click][] para copiar um bloco só.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Segure [accent][[L-Ctrl][] enquanto arrasta as esteiras para gerar automaticamente um caminho. hint.conveyorPathfind = Segure [accent][[L-Ctrl][] enquanto arrasta as esteiras para gerar automaticamente um caminho.
hint.conveyorPathfind.mobile = Ative o \ue844 [accent]modo diagonal[] e arraste as esteiras para gerar automaticamente um caminho. hint.conveyorPathfind.mobile = Ative o \ue844 [accent]modo diagonal[] e arraste as esteiras para gerar automaticamente um caminho.
hint.boost = Segure [accent][[L-Shift][] para voar sobre obstáculos com a sua unidade.\n\nApenas algumas unidades terrestres tem propulsores. hint.boost = Segure [accent][[L-Shift][] para voar sobre obstáculos com a sua unidade.\n\nApenas algumas unidades terrestres tem propulsores.

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1773,6 +1773,7 @@ hint.launch = Odată ce s-au strâns suficiente resurse, poți [accent]Lansa[] c
hint.launch.mobile = Odată ce s-au strâns suficiente resurse, poți [accent]Lansa[] către o altă zonă selectând sectoarele învecinate folosind \ue827 [accent]Harta[] din \ue88c [accent]Meniu[]. hint.launch.mobile = Odată ce s-au strâns suficiente resurse, poți [accent]Lansa[] către o altă zonă selectând sectoarele învecinate folosind \ue827 [accent]Harta[] din \ue88c [accent]Meniu[].
hint.schematicSelect = Ține apăsat [accent][[F][] și trage pt a selecta blocuri pt copiere.\n\n[accent][[Click pe rotiță][] pt a copia un singur tip de bloc. hint.schematicSelect = Ține apăsat [accent][[F][] și trage pt a selecta blocuri pt copiere.\n\n[accent][[Click pe rotiță][] pt a copia un singur tip de bloc.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Ține apăsat [accent][[Ctrl][] în timp ce plasezi benzi pt a genera automat o cale între 2 puncte. hint.conveyorPathfind = Ține apăsat [accent][[Ctrl][] în timp ce plasezi benzi pt a genera automat o cale între 2 puncte.
hint.conveyorPathfind.mobile = Activează \ue844 [accent]modul diagonal[] și plasează benzi pt a genera automat o cale între 2 puncte. hint.conveyorPathfind.mobile = Activează \ue844 [accent]modul diagonal[] și plasează benzi pt a genera automat o cale între 2 puncte.
hint.boost = Ține apăsat [accent][[Shift][] pt a zbura peste obstacole cu unitatea ta.\n\nDoar câteva unități de artilerie au propulsoare. hint.boost = Ține apăsat [accent][[Shift][] pt a zbura peste obstacole cu unitatea ta.\n\nDoar câteva unități de artilerie au propulsoare.

View File

@@ -1773,6 +1773,7 @@ hint.launch = Как только будет собрано достаточно
hint.launch.mobile = Как только будет собрано достаточно ресурсов, вы сможете осуществить [accent]Запуск[], выбрав близлежащие секторы на \ue827 [accent]Карте[] в \ue88c [accent]Меню[]. hint.launch.mobile = Как только будет собрано достаточно ресурсов, вы сможете осуществить [accent]Запуск[], выбрав близлежащие секторы на \ue827 [accent]Карте[] в \ue88c [accent]Меню[].
hint.schematicSelect = Зажмите [accent][[F][] и переместите, чтобы выбрать блоки для копирования и вставки.\n\nЩелкните [accent][[колёсиком][] по блоку для копирования. hint.schematicSelect = Зажмите [accent][[F][] и переместите, чтобы выбрать блоки для копирования и вставки.\n\nЩелкните [accent][[колёсиком][] по блоку для копирования.
hint.rebuildSelect = Удерживайте [accent][[B][] и перетаскивайте, чтобы выбрать уничтоженные блоки.\nОни будут перестроены автоматически. hint.rebuildSelect = Удерживайте [accent][[B][] и перетаскивайте, чтобы выбрать уничтоженные блоки.\nОни будут перестроены автоматически.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Удерживайте [accent][[Л-Ctrl][] при размещении конвейеров для автоматической прокладки пути. hint.conveyorPathfind = Удерживайте [accent][[Л-Ctrl][] при размещении конвейеров для автоматической прокладки пути.
hint.conveyorPathfind.mobile = Включите \ue844 [accent]диагональный режим[] и перетащите конвейеры для автоматической прокладки пути. hint.conveyorPathfind.mobile = Включите \ue844 [accent]диагональный режим[] и перетащите конвейеры для автоматической прокладки пути.
hint.boost = Удерживайте [accent][[Л-Shift][], чтобы пролететь над препятствиями при помощи вашей единицы.\n\nТолько некоторые наземные единицы могут взлетать. hint.boost = Удерживайте [accent][[Л-Shift][], чтобы пролететь над препятствиями при помощи вашей единицы.\n\nТолько некоторые наземные единицы могут взлетать.

View File

@@ -1776,6 +1776,7 @@ hint.launch = Jednom kada je dovoljno resursa skupljeno, možeš [accent]Lansira
hint.launch.mobile = Jednom kada je dovoljno resursa skupljeno, možeš [accent]Lansirati[] tako što bi izabrao obljižnji sektor iz \ue827 [accent]Mape[] u \ue88c [accent]Meniju[]. hint.launch.mobile = Jednom kada je dovoljno resursa skupljeno, možeš [accent]Lansirati[] tako što bi izabrao obljižnji sektor iz \ue827 [accent]Mape[] u \ue88c [accent]Meniju[].
hint.schematicSelect = Drži [accent][[F][] i vuci da bi izabrao blokove da kopiraš i postaviš.\n\n[accent][[Srednji Klick][] Da iskopiraš samo jedan tip blokova. hint.schematicSelect = Drži [accent][[F][] i vuci da bi izabrao blokove da kopiraš i postaviš.\n\n[accent][[Srednji Klick][] Da iskopiraš samo jedan tip blokova.
hint.rebuildSelect = Drži [accent][[B][] i vuci da bi izabrao planove izabranih blokova.\nOvo će automatski ponovo da ih sagradi. hint.rebuildSelect = Drži [accent][[B][] i vuci da bi izabrao planove izabranih blokova.\nOvo će automatski ponovo da ih sagradi.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Drži [accent][[L-Ctrl][] dok vučeš trake da automatski stvoriš put. hint.conveyorPathfind = Drži [accent][[L-Ctrl][] dok vučeš trake da automatski stvoriš put.
hint.conveyorPathfind.mobile = Osposobi \ue844 [accent]dijagonalni mod[] dok vučeš trake da automatski stvoriš put. hint.conveyorPathfind.mobile = Osposobi \ue844 [accent]dijagonalni mod[] dok vučeš trake da automatski stvoriš put.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1781,6 +1781,7 @@ hint.launch = เมื่อเก็บทรัพยากรเยอะพ
hint.launch.mobile = เมื่อเก็บทรัพยากรเยอะพอ คุณสามารถ[accent]ส่งแกนกลาง[]โดยการเลือกเซ็กเตอร์จาก \ue827 [accent]แผนที่[] ใน \ue88c [accent]เมนู[] hint.launch.mobile = เมื่อเก็บทรัพยากรเยอะพอ คุณสามารถ[accent]ส่งแกนกลาง[]โดยการเลือกเซ็กเตอร์จาก \ue827 [accent]แผนที่[] ใน \ue88c [accent]เมนู[]
hint.schematicSelect = กด [accent][[F][] แล้วลากเพื่อเลือกบล็อกที่จะคัดลอกและวาง\n\n[accent][[คลิ๊กกลาง][] เพื่อคัดลอกบล็อกชนิดเดียว hint.schematicSelect = กด [accent][[F][] แล้วลากเพื่อเลือกบล็อกที่จะคัดลอกและวาง\n\n[accent][[คลิ๊กกลาง][] เพื่อคัดลอกบล็อกชนิดเดียว
hint.rebuildSelect = กด [accent][[B][] แล้วลากเพื่อเลือกแปลนบล็อกที่ถูกทำลาย\nแปลนบล็อกที่เลือกจะถูกสร้างใหม้โดยอัตโนมัติ hint.rebuildSelect = กด [accent][[B][] แล้วลากเพื่อเลือกแปลนบล็อกที่ถูกทำลาย\nแปลนบล็อกที่เลือกจะถูกสร้างใหม้โดยอัตโนมัติ
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = กด [accent][[L-Ctrl][] ในขณะที่กำลังลากสายพานเพื่อสร้างเส้นทางแบบอัตโนมัติ hint.conveyorPathfind = กด [accent][[L-Ctrl][] ในขณะที่กำลังลากสายพานเพื่อสร้างเส้นทางแบบอัตโนมัติ
hint.conveyorPathfind.mobile = เปิดใช้งาน \ue844 [accent]โหมดแนวทแยง[] แล้วลากสายพานเพื่อสร้างเส้นทางแบบอัตโนมัติ hint.conveyorPathfind.mobile = เปิดใช้งาน \ue844 [accent]โหมดแนวทแยง[] แล้วลากสายพานเพื่อสร้างเส้นทางแบบอัตโนมัติ
hint.boost = กด [accent][[L-Shift][] เพื่อบูสต์ข้ามสิ่งกีดขวางด้วยยูนิตของคุณ\n\nยูนิตพื้นดินบางประเภทเท่านั้นที่บินได้ hint.boost = กด [accent][[L-Shift][] เพื่อบูสต์ข้ามสิ่งกีดขวางด้วยยูนิตของคุณ\n\nยูนิตพื้นดินบางประเภทเท่านั้นที่บินได้

View File

@@ -1758,6 +1758,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \ue827 [accent]Map[] in the \ue88c [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \ue844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -1774,6 +1774,7 @@ hint.launch = Yeterince kaynak topladıktan sonra, üssünüzü başka bir sekt
hint.launch.mobile = Yeterince kaynak topladıktan sonra, üssünüzü başka bir sektöre [accent]fırlatmak[] için sağ alttaki \ue88c [accent]menüden[] \ue827 [accent]harita[] tuşuna basın. hint.launch.mobile = Yeterince kaynak topladıktan sonra, üssünüzü başka bir sektöre [accent]fırlatmak[] için sağ alttaki \ue88c [accent]menüden[] \ue827 [accent]harita[] tuşuna basın.
hint.schematicSelect = İstediğiniz blokları kopyalayıp yapıştırmak için [accent][[F][] tuşunu basılı tutun ve farenizi sürükleyin.\n\n[accent][[Orta Tuş'a (Fare Tekerleği'ne)][] basarak tek bir blok seçebilirsiniz. hint.schematicSelect = İstediğiniz blokları kopyalayıp yapıştırmak için [accent][[F][] tuşunu basılı tutun ve farenizi sürükleyin.\n\n[accent][[Orta Tuş'a (Fare Tekerleği'ne)][] basarak tek bir blok seçebilirsiniz.
hint.rebuildSelect = [accent][[B][] ye basılı tutarak, yok edilmiş blokları seç.\nBu binaları yeniden inşaa etmeni sağlar. hint.rebuildSelect = [accent][[B][] ye basılı tutarak, yok edilmiş blokları seç.\nBu binaları yeniden inşaa etmeni sağlar.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Konveyörler ile yol yaparken bir noktadan diğer noktaya otomatik yol oluşturmak için [accent][[Sol CTRL][] tuşunu basılı tutun. hint.conveyorPathfind = Konveyörler ile yol yaparken bir noktadan diğer noktaya otomatik yol oluşturmak için [accent][[Sol CTRL][] tuşunu basılı tutun.
hint.conveyorPathfind.mobile = Konveyörler ile yol yaparken bir noktadan diğer noktaya otomatik yol oluşturmak için \ue844 [accent]Çapraz Mod'u[] etkinleştirin. hint.conveyorPathfind.mobile = Konveyörler ile yol yaparken bir noktadan diğer noktaya otomatik yol oluşturmak için \ue844 [accent]Çapraz Mod'u[] etkinleştirin.
hint.boost = Bazı yer birimleri duvarların, taretlerin, diğer birimlerin üstünden uçma özelliği vardır. [accent][[Sol Shift][] tuşunu basılı tutarak bazı yer üniteleri ile uçabilirsiniz. hint.boost = Bazı yer birimleri duvarların, taretlerin, diğer birimlerin üstünden uçma özelliği vardır. [accent][[Sol Shift][] tuşunu basılı tutarak bazı yer üniteleri ile uçabilirsiniz.

View File

@@ -1787,6 +1787,7 @@ hint.launch = Як тільки буде зібрано достатньо ре
hint.launch.mobile = Як тільки буде зібрано достатньо ресурсів, ви зможете зробити [accent]Запуск[] за допомогою вибору найближчих секторів з \ue827 [accent]мапи[] у \ue88c [accent]меню[]. hint.launch.mobile = Як тільки буде зібрано достатньо ресурсів, ви зможете зробити [accent]Запуск[] за допомогою вибору найближчих секторів з \ue827 [accent]мапи[] у \ue88c [accent]меню[].
hint.schematicSelect = Утримуйте [accent][[F][] і тягніть, щоби вибрати блоки для їхнього подальшого копіювання і вставлення.\n\nНатисніть [accent][[СКМ][], щоби скопіювати певний тип блоку. hint.schematicSelect = Утримуйте [accent][[F][] і тягніть, щоби вибрати блоки для їхнього подальшого копіювання і вставлення.\n\nНатисніть [accent][[СКМ][], щоби скопіювати певний тип блоку.
hint.rebuildSelect = Утримуючи [accent][[B][], протягніть, щоби вибрати зруйновані проєкти блоків.\nЦе призведе до їхнього автоматичного відновлення. hint.rebuildSelect = Утримуючи [accent][[B][], протягніть, щоби вибрати зруйновані проєкти блоків.\nЦе призведе до їхнього автоматичного відновлення.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Утримуйте [accent][[лівий Ctrl][], коли тягнете конвеєри, щоб автоматично прокласти шлях. hint.conveyorPathfind = Утримуйте [accent][[лівий Ctrl][], коли тягнете конвеєри, щоб автоматично прокласти шлях.
hint.conveyorPathfind.mobile = Увімкніть \ue844 [accent]діагональний режим[] і тягніть конвеєри, щоб автоматично прокласти шлях. hint.conveyorPathfind.mobile = Увімкніть \ue844 [accent]діагональний режим[] і тягніть конвеєри, щоб автоматично прокласти шлях.

View File

@@ -1775,6 +1775,7 @@ hint.launch = Sau khi thu thập đủ tài nguyên, bạn có thể [accent]Ph
hint.launch.mobile = Sau khi thu thập đủ tài nguyên, bạn có thể [accent]Phóng[] bằng cách chọn các khu vực lân cận từ \ue827 [accent]Bản đồ[] trong \ue88c [accent]Menu[]. hint.launch.mobile = Sau khi thu thập đủ tài nguyên, bạn có thể [accent]Phóng[] bằng cách chọn các khu vực lân cận từ \ue827 [accent]Bản đồ[] trong \ue88c [accent]Menu[].
hint.schematicSelect = Giữ [accent][[F][] và kéo để chọn các khối để sao chép và dán.\n\n[accent][[Middle Click][] để sao chép một khối. hint.schematicSelect = Giữ [accent][[F][] và kéo để chọn các khối để sao chép và dán.\n\n[accent][[Middle Click][] để sao chép một khối.
hint.rebuildSelect = Giữ [accent][[B][] và kéo để chọn các khối bị hỏng.\nChúng sẽ được tự động được xây lại. hint.rebuildSelect = Giữ [accent][[B][] và kéo để chọn các khối bị hỏng.\nChúng sẽ được tự động được xây lại.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Giữ [accent][[L-Ctrl][] trong khi kéo băng chuyền để tự động tạo đường dẫn. hint.conveyorPathfind = Giữ [accent][[L-Ctrl][] trong khi kéo băng chuyền để tự động tạo đường dẫn.
hint.conveyorPathfind.mobile = Mở \ue844 [accent]chế độ đường chéo[] và kéo băng chuyền để tự động tạo đường dẫn. hint.conveyorPathfind.mobile = Mở \ue844 [accent]chế độ đường chéo[] và kéo băng chuyền để tự động tạo đường dẫn.
hint.boost = Giữ [accent][[L-Shift][] bay qua các chướng ngại vật với quân lính hiện tại của bạn.\n\nChỉ một số quân lính mặt đất có thể bay được. hint.boost = Giữ [accent][[L-Shift][] bay qua các chướng ngại vật với quân lính hiện tại của bạn.\n\nChỉ một số quân lính mặt đất có thể bay được.

View File

@@ -1788,6 +1788,7 @@ hint.launch = 一旦收集了足够的资源,您就可以通过右下角的\ue
hint.launch.mobile = 一旦收集到足够的资源,您就可以通过\ue88c[accent]菜单[]中的\ue827[accent]地图[]选择附近的区块[accent]发射[]核心。 hint.launch.mobile = 一旦收集到足够的资源,您就可以通过\ue88c[accent]菜单[]中的\ue827[accent]地图[]选择附近的区块[accent]发射[]核心。
hint.schematicSelect = 按住[accent][[F][]键用鼠标框选建筑以复制粘贴。 \n\n[accent][鼠标中键][]复制单个建筑。 hint.schematicSelect = 按住[accent][[F][]键用鼠标框选建筑以复制粘贴。 \n\n[accent][鼠标中键][]复制单个建筑。
hint.rebuildSelect = 按住[accent][[B][]用鼠标框选被摧毁的建筑以自动重建。 hint.rebuildSelect = 按住[accent][[B][]用鼠标框选被摧毁的建筑以自动重建。
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = 按住[accent][[L-Ctrl][]键并拖动传送带,使其自动寻路。 hint.conveyorPathfind = 按住[accent][[L-Ctrl][]键并拖动传送带,使其自动寻路。
hint.conveyorPathfind.mobile = 启用\ue844[accent]传送带自动寻路[]后,拖动传送带可使其自动寻路。 hint.conveyorPathfind.mobile = 启用\ue844[accent]传送带自动寻路[]后,拖动传送带可使其自动寻路。

View File

@@ -1784,6 +1784,7 @@ hint.launch = 一旦蒐集到足夠的資源,你可以透過右下角的 \ue82
hint.launch.mobile = 一旦蒐集到足夠的資源,你可以透過選單中的 \ue827 [accent]地圖[]來選取你要[accent]發射[]的區域。 hint.launch.mobile = 一旦蒐集到足夠的資源,你可以透過選單中的 \ue827 [accent]地圖[]來選取你要[accent]發射[]的區域。
hint.schematicSelect = 按住[accent][[F][]並拖曳可以選取方塊並貼上。\n\n按下[accent][[滑鼠中鍵][]可以複製單一方塊。 hint.schematicSelect = 按住[accent][[F][]並拖曳可以選取方塊並貼上。\n\n按下[accent][[滑鼠中鍵][]可以複製單一方塊。
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = 在建造輸送帶時按下[accent][[L-Ctrl][]可以自動產生路徑。 hint.conveyorPathfind = 在建造輸送帶時按下[accent][[L-Ctrl][]可以自動產生路徑。
hint.conveyorPathfind.mobile = 啟用 \ue844 [accent]對角線模式[]可以在建造輸送帶時自動產生路徑。 hint.conveyorPathfind.mobile = 啟用 \ue844 [accent]對角線模式[]可以在建造輸送帶時自動產生路徑。
hint.boost = 按住[accent][[L-Shift][]可以帶著你的機甲一起飛越障礙物\n\n只有少數陸行機甲有推進器。 hint.boost = 按住[accent][[L-Shift][]可以帶著你的機甲一起飛越障礙物\n\n只有少數陸行機甲有推進器。

View File

@@ -154,3 +154,4 @@ zenonet
AyuKo-o AyuKo-o
JojoFR1 JojoFR1
Xasmedy Xasmedy
xStaBUx

View File

@@ -3055,7 +3055,7 @@ public class Blocks{
progress = PartProgress.recoil; progress = PartProgress.recoil;
recoilIndex = f; recoilIndex = f;
under = true; under = true;
moves.add(new PartMove(PartProgress.recoil, 0f, -1.5f, 0f)); moveY = -1.5f;
}}); }});
} }
}}; }};
@@ -3122,6 +3122,15 @@ public class Blocks{
}}; }};
}} }}
); );
drawer = new DrawTurret(){{
parts.add(new RegionPart("-mid"){{
progress = PartProgress.recoil;
under = true;
moveY = -1f;
}});
}};
reload = 18f; reload = 18f;
range = 220f; range = 220f;
size = 2; size = 2;
@@ -3130,7 +3139,7 @@ public class Blocks{
shoot.shotDelay = 5f; shoot.shotDelay = 5f;
shoot.shots = 2; shoot.shots = 2;
recoil = 2f; recoil = 1f;
rotateSpeed = 15f; rotateSpeed = 15f;
inaccuracy = 17f; inaccuracy = 17f;
shootCone = 35f; shootCone = 35f;
@@ -3479,12 +3488,21 @@ public class Blocks{
}} }}
); );
drawer = new DrawTurret(){{
parts.add(new RegionPart("-barrel"){{
progress = PartProgress.recoil.delay(0.5f); //Since recoil is 1-0, cut from the start instead of the end.
under = true;
turretHeatLayer = Layer.turret - 0.0001f;
moveY = -1.5f;
}});
}};
size = 2; size = 2;
range = 190f; range = 190f;
reload = 31f; reload = 31f;
consumeAmmoOnce = false; consumeAmmoOnce = false;
ammoEjectBack = 3f; ammoEjectBack = 3f;
recoil = 3f; recoil = 2f;
shake = 1f; shake = 1f;
shoot.shots = 4; shoot.shots = 4;
shoot.shotDelay = 3f; shoot.shotDelay = 3f;
@@ -3776,7 +3794,8 @@ public class Blocks{
explodeRange = 20f; explodeRange = 20f;
}} }}
); );
shootY = 8.75f; shootY = 10f;
shoot = new ShootBarrel(){{ shoot = new ShootBarrel(){{
barrels = new float[]{ barrels = new float[]{
0f, 1f, 0f, 0f, 1f, 0f,
@@ -3784,10 +3803,25 @@ public class Blocks{
-3f, 0f, 0f, -3f, 0f, 0f,
}; };
}}; }};
recoils = 3;
drawer = new DrawTurret(){{
for(int i = 3; i > 0; i--){
int f = i;
parts.add(new RegionPart("-barrel-" + i){{
progress = PartProgress.recoil;
recoilIndex = f - 1;
under = true;
moveY = -2f;
}});
}
}};
reload = 8f; reload = 8f;
range = 200f; range = 200f;
size = 3; size = 3;
recoil = 3f; recoil = 1.5f;
recoilTime = 10;
rotateSpeed = 10f; rotateSpeed = 10f;
inaccuracy = 10f; inaccuracy = 10f;
shootCone = 30f; shootCone = 30f;

View File

@@ -72,6 +72,8 @@ public class Renderer implements ApplicationListener{
landPTimer, landPTimer,
//intensity for screen shake //intensity for screen shake
shakeIntensity, shakeIntensity,
//reduction rate of screen shake
shakeReduction,
//current duration of screen shake //current duration of screen shake
shakeTime; shakeTime;
//for landTime > 0: if true, core is currently *launching*, otherwise landing. //for landTime > 0: if true, core is currently *launching*, otherwise landing.
@@ -83,14 +85,15 @@ public class Renderer implements ApplicationListener{
Shaders.init(); Shaders.init();
Events.on(ResetEvent.class, e -> { Events.on(ResetEvent.class, e -> {
shakeTime = shakeIntensity = 0f; shakeTime = shakeIntensity = shakeReduction = 0f;
camShakeOffset.setZero(); camShakeOffset.setZero();
}); });
} }
public void shake(float intensity, float duration){ public void shake(float intensity, float duration){
shakeIntensity = Math.max(shakeIntensity, intensity); shakeIntensity = Math.max(shakeIntensity, Mathf.clamp(intensity, 0, 100));
shakeTime = Math.max(shakeTime, duration); shakeTime = Math.max(shakeTime, duration);
shakeReduction = shakeIntensity / shakeTime;
} }
public void addEnvRenderer(int mask, Runnable render){ public void addEnvRenderer(int mask, Runnable render){
@@ -210,7 +213,7 @@ public class Renderer implements ApplicationListener{
float intensity = shakeIntensity * (settings.getInt("screenshake", 4) / 4f) * 0.75f; float intensity = shakeIntensity * (settings.getInt("screenshake", 4) / 4f) * 0.75f;
camShakeOffset.setToRandomDirection().scl(Mathf.random(intensity)); camShakeOffset.setToRandomDirection().scl(Mathf.random(intensity));
camera.position.add(camShakeOffset); camera.position.add(camShakeOffset);
shakeIntensity -= 0.25f * Time.delta; shakeIntensity -= shakeReduction * Time.delta;
shakeTime -= Time.delta; shakeTime -= Time.delta;
shakeIntensity = Mathf.clamp(shakeIntensity, 0f, 100f); shakeIntensity = Mathf.clamp(shakeIntensity, 0f, 100f);
}else{ }else{

View File

@@ -51,7 +51,7 @@ public class UI implements ApplicationListener, Loadable{
public AboutDialog about; public AboutDialog about;
public GameOverDialog restart; public GameOverDialog restart;
public CustomGameDialog custom; public CustomGameDialog custom;
public MapsDialog maps; public EditorMapsDialog maps;
public LoadDialog load; public LoadDialog load;
public DiscordDialog discord; public DiscordDialog discord;
public JoinDialog join; public JoinDialog join;
@@ -195,7 +195,7 @@ public class UI implements ApplicationListener, Loadable{
bans = new BansDialog(); bans = new BansDialog();
admins = new AdminsDialog(); admins = new AdminsDialog();
traces = new TraceDialog(); traces = new TraceDialog();
maps = new MapsDialog(); maps = new EditorMapsDialog();
content = new ContentInfoDialog(); content = new ContentInfoDialog();
planet = new PlanetDialog(); planet = new PlanetDialog();
research = new ResearchDialog(); research = new ResearchDialog();

View File

@@ -554,7 +554,7 @@ public class BulletType extends Content implements Cloneable{
public void init(Bullet b){ public void init(Bullet b){
if(killShooter && b.owner() instanceof Healthc h){ if(killShooter && b.owner() instanceof Healthc h && !h.dead()){
h.kill(); h.kill();
} }
@@ -700,7 +700,6 @@ public class BulletType extends Content implements Cloneable{
return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null); return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null);
} }
public @Nullable Bullet create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Mover mover){ public @Nullable Bullet create(Entityc owner, Team team, float x, float y, float angle, float velocityScl, float lifetimeScl, Mover mover){
return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null, mover); return create(owner, team, x, y, angle, -1, velocityScl, lifetimeScl, null, mover);
} }
@@ -732,24 +731,27 @@ public class BulletType extends Content implements Cloneable{
Unit spawned = spawnUnit.create(team); Unit spawned = spawnUnit.create(team);
spawned.set(x, y); spawned.set(x, y);
spawned.rotation = angle; spawned.rotation = angle;
//immediately spawn at top speed, since it was launched //immediately spawn at top speed, since it was launched
if(spawnUnit.missileAccelTime <= 0f){ if(spawnUnit.missileAccelTime <= 0f){
spawned.vel.trns(angle, spawnUnit.speed); spawned.vel.trns(angle, spawnUnit.speed);
} }
//assign unit owner //assign unit owner
if(spawned.controller() instanceof MissileAI ai){ if(spawned.controller() instanceof MissileAI ai){
if(owner instanceof Unit unit){ if(owner instanceof Unit unit){
ai.shooter = unit; ai.shooter = unit;
} }
if(owner instanceof ControlBlock control){ if(owner instanceof ControlBlock control){
ai.shooter = control.unit(); ai.shooter = control.unit();
} }
} }
spawned.add(); spawned.add();
} }
//Since bullet init is never called, handle killing shooter here
if(killShooter && owner instanceof Healthc h && !h.dead()) h.kill();
//no bullet returned //no bullet returned
return null; return null;
} }

View File

@@ -53,7 +53,9 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
while(it.hasNext()){ while(it.hasNext()){
BuildPlan plan = it.next(); BuildPlan plan = it.next();
Tile tile = world.tile(plan.x, plan.y); Tile tile = world.tile(plan.x, plan.y);
if(tile == null || (plan.breaking && tile.block() == Blocks.air) || (!plan.breaking && ((tile.build != null && tile.build.rotation == plan.rotation) || !plan.block.rotate) && tile.block() == plan.block)){ if(tile == null || (plan.breaking && tile.block() == Blocks.air) || (!plan.breaking && ((tile.build != null && tile.build.rotation == plan.rotation) || !plan.block.rotate) &&
(tile.block() == plan.block || (plan.block != null && (plan.block.isOverlay() && plan.block == tile.overlay() || (plan.block.isFloor() && plan.block == tile.floor())))))){
it.remove(); it.remove();
} }
} }

View File

@@ -323,13 +323,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
} }
void sendMessage(String text){ void sendMessage(String text){
if(isLocal()){ sendMessage(text, null, null);
if(ui != null){
ui.chatfrag.addMessage(text);
}
}else{
Call.sendMessage(con, text, null, null);
}
} }
void sendMessage(String text, Player from){ void sendMessage(String text, Player from){
@@ -346,6 +340,14 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
} }
} }
void sendUnformatted(String unformatted){
sendUnformatted(null, unformatted);
}
void sendUnformatted(Player from, String unformatted){
sendMessage(netServer.chatFormatter.format(from, unformatted), from, unformatted);
}
PlayerInfo getInfo(){ PlayerInfo getInfo(){
if(isLocal()){ if(isLocal()){
throw new IllegalArgumentException("Local players cannot be traced and do not have info."); throw new IllegalArgumentException("Local players cannot be traced and do not have info.");

View File

@@ -78,8 +78,8 @@ public class RegionPart extends DrawPart{
mx += move.x * p; mx += move.x * p;
my += move.y * p; my += move.y * p;
mr += move.rot * p; mr += move.rot * p;
gx += move.gx; gx += move.gx * p;
gy += move.gy; gy += move.gy * p;
} }
} }
@@ -95,7 +95,7 @@ public class RegionPart extends DrawPart{
//can be null //can be null
var region = drawRegion ? regions[Math.min(i, regions.length - 1)] : null; var region = drawRegion ? regions[Math.min(i, regions.length - 1)] : null;
float sign = (i == 0 ? 1 : -1) * params.sideMultiplier; float sign = (i == 0 ? 1 : -1) * params.sideMultiplier;
Tmp.v1.set((x + mx) * sign * Draw.xscl, (y + my) * Draw.yscl).rotateRadExact((params.rotation - 90) * Mathf.degRad); Tmp.v1.set((x + mx) * sign, y + my).rotateRadExact((params.rotation - 90) * Mathf.degRad);
float float
rx = params.x + Tmp.v1.x, rx = params.x + Tmp.v1.x,

View File

@@ -257,13 +257,13 @@ public class EventType{
} }
} }
/** Called when the player configures a specific building. */ /** Called when a specific building has its configuration changed. */
public static class ConfigEvent{ public static class ConfigEvent{
public final Building tile; public final Building tile;
public final Player player; public final @Nullable Player player;
public final Object value; public final Object value;
public ConfigEvent(Building tile, Player player, Object value){ public ConfigEvent(Building tile, @Nullable Player player, Object value){
this.tile = tile; this.tile = tile;
this.player = player; this.player = player;
this.value = value; this.value = value;
@@ -473,6 +473,18 @@ public class EventType{
} }
} }
public static class BuildRotateEvent{
public final Building build;
public final @Nullable Unit unit;
public final int previous;
public BuildRotateEvent(Building build, @Nullable Unit unit, int previous){
this.build = build;
this.unit = unit;
this.previous = previous;
}
}
/** /**
* Called when a player or drone begins building something. * Called when a player or drone begins building something.
* This does not necessarily happen when a new ConstructBlock is created. * This does not necessarily happen when a new ConstructBlock is created.

View File

@@ -12,20 +12,15 @@ import arc.scene.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.*; import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.input.Placement.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.*; import mindustry.world.*;
import java.util.*;
import static arc.Core.*; import static arc.Core.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
import static mindustry.input.PlaceMode.*; import static mindustry.input.PlaceMode.*;
@@ -119,19 +114,7 @@ public class DesktopInput extends InputHandler{
if(Core.input.keyDown(Binding.schematic_select)){ if(Core.input.keyDown(Binding.schematic_select)){
drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize); drawSelection(schemX, schemY, cursorX, cursorY, Vars.maxSchematicSize);
}else if(Core.input.keyDown(Binding.rebuild_select)){ }else if(Core.input.keyDown(Binding.rebuild_select)){
//TODO color? drawRebuildSelection(schemX, schemY, cursorX, cursorY);
drawSelection(schemX, schemY, cursorX, cursorY, 0, Pal.sapBulletBack, Pal.sapBullet);
NormalizeDrawResult result = Placement.normalizeDrawArea(Blocks.air, schemX, schemY, cursorX, cursorY, false, 0, 1f);
Tmp.r1.set(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
for(BlockPlan plan : player.team().data().plans){
Block block = content.block(plan.block);
if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){
drawSelected(plan.x, plan.y, content.block(plan.block), Pal.sapBullet);
}
}
} }
} }
@@ -529,20 +512,8 @@ public class DesktopInput extends InputHandler{
schemX = -1; schemX = -1;
schemY = -1; schemY = -1;
}else if(input.keyRelease(Binding.rebuild_select)){ }else if(input.keyRelease(Binding.rebuild_select)){
//TODO rebuild!!!
NormalizeResult result = Placement.normalizeArea(schemX, schemY, rawCursorX, rawCursorY, rotation, false, 999999999);
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
Iterator<BlockPlan> broken = player.team().data().plans.iterator();
while(broken.hasNext()){
BlockPlan plan = broken.next();
Block block = content.block(plan.block);
if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){
player.unit().addBuild(new BuildPlan(plan.x, plan.y, plan.rotation, content.block(plan.block), plan.config));
}
}
rebuildArea(schemX, schemY, rawCursorX, rawCursorY);
schemX = -1; schemX = -1;
schemY = -1; schemY = -1;
} }

View File

@@ -464,10 +464,12 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
} }
if(player != null) build.lastAccessed = player.name; if(player != null) build.lastAccessed = player.name;
int previous = build.rotation;
build.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4); build.rotation = Mathf.mod(build.rotation + Mathf.sign(direction), 4);
build.updateProximity(); build.updateProximity();
build.noSleep(); build.noSleep();
Fx.rotateBlock.at(build.x, build.y, build.block.size); Fx.rotateBlock.at(build.x, build.y, build.block.size);
Events.fire(new BuildRotateEvent(build, player.unit(), previous));
} }
@Remote(targets = Loc.both, called = Loc.both, forward = true) @Remote(targets = Loc.both, called = Loc.both, forward = true)
@@ -1164,6 +1166,21 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y); Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
} }
protected void drawRebuildSelection(int x, int y, int x2, int y2){
drawSelection(x, y, x2, y2, 0, Pal.sapBulletBack, Pal.sapBullet);
NormalizeDrawResult result = Placement.normalizeDrawArea(Blocks.air, x, y, x2, y2, false, 0, 1f);
Tmp.r1.set(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
for(BlockPlan plan : player.team().data().plans){
Block block = content.block(plan.block);
if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){
drawSelected(plan.x, plan.y, content.block(plan.block), Pal.sapBullet);
}
}
}
protected void drawBreakSelection(int x1, int y1, int x2, int y2){ protected void drawBreakSelection(int x1, int y1, int x2, int y2){
drawBreakSelection(x1, y1, x2, y2, maxLength); drawBreakSelection(x1, y1, x2, y2, maxLength);
} }
@@ -1651,6 +1668,20 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
} }
} }
public void rebuildArea(int x, int y, int x2, int y2){
NormalizeResult result = Placement.normalizeArea(x, y, x2, y2, rotation, false, 999999999);
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
Iterator<BlockPlan> broken = player.team().data().plans.iterator();
while(broken.hasNext()){
BlockPlan plan = broken.next();
Block block = content.block(plan.block);
if(block.bounds(plan.x, plan.y, Tmp.r2).overlaps(Tmp.r1)){
player.unit().addBuild(new BuildPlan(plan.x, plan.y, plan.rotation, content.block(plan.block), plan.config));
}
}
}
public void tryBreakBlock(int x, int y){ public void tryBreakBlock(int x, int y){
if(validBreak(x, y)){ if(validBreak(x, y)){
breakBlock(x, y); breakBlock(x, y);

View File

@@ -55,7 +55,7 @@ public class MobileInput extends InputHandler implements GestureListener{
/** Whether the player is currently shifting all placed tiles. */ /** Whether the player is currently shifting all placed tiles. */
public boolean selecting; public boolean selecting;
/** Whether the player is currently in line-place mode. */ /** Whether the player is currently in line-place mode. */
public boolean lineMode, schematicMode; public boolean lineMode, schematicMode, rebuildMode;
/** Current place mode. */ /** Current place mode. */
public PlaceMode mode = none; public PlaceMode mode = none;
/** Whether no recipe was available when switching to break mode. */ /** Whether no recipe was available when switching to break mode. */
@@ -208,6 +208,8 @@ public class MobileInput extends InputHandler implements GestureListener{
if(schematicMode){ if(schematicMode){
block = null; block = null;
mode = none; mode = none;
}else{
rebuildMode = false;
} }
} }
}).update(i -> { }).update(i -> {
@@ -219,37 +221,45 @@ public class MobileInput extends InputHandler implements GestureListener{
}); });
//confirm button //confirm button
table.button(Icon.ok, Styles.clearNonei, () -> { table.button(Icon.ok, Styles.clearNoneTogglei, () -> {
for(BuildPlan plan : selectPlans){ if(schematicMode){
Tile tile = plan.tile(); rebuildMode = !rebuildMode;
}else{
for(BuildPlan plan : selectPlans){
Tile tile = plan.tile();
//actually place/break all selected blocks //actually place/break all selected blocks
if(tile != null){ if(tile != null){
if(!plan.breaking){ if(!plan.breaking){
if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){ if(validPlace(plan.x, plan.y, plan.block, plan.rotation)){
BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null); BuildPlan other = getPlan(plan.x, plan.y, plan.block.size, null);
BuildPlan copy = plan.copy(); BuildPlan copy = plan.copy();
if(other == null){ if(other == null){
player.unit().addBuild(copy); player.unit().addBuild(copy);
}else if(!other.breaking && other.x == plan.x && other.y == plan.y && other.block.size == plan.block.size){ }else if(!other.breaking && other.x == plan.x && other.y == plan.y && other.block.size == plan.block.size){
player.unit().plans().remove(other); player.unit().plans().remove(other);
player.unit().addBuild(copy); player.unit().addBuild(copy);
}
} }
}
rotation = plan.rotation; rotation = plan.rotation;
}else{ }else{
tryBreakBlock(tile.x, tile.y); tryBreakBlock(tile.x, tile.y);
}
} }
} }
}
//move all current plans to removal array so they fade out //move all current plans to removal array so they fade out
removals.addAll(selectPlans.select(r -> !r.breaking)); removals.addAll(selectPlans.select(r -> !r.breaking));
selectPlans.clear(); selectPlans.clear();
selecting = false; selecting = false;
}).visible(() -> !selectPlans.isEmpty()).name("confirmplace"); }
}).visible(() -> !selectPlans.isEmpty() || schematicMode || rebuildMode).update(i -> {
i.getStyle().imageUp = schematicMode || rebuildMode ? Icon.wrench : Icon.ok;
i.setChecked(rebuildMode);
}).name("confirmplace");
} }
boolean showCancel(){ boolean showCancel(){
@@ -366,9 +376,10 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override @Override
public void drawTop(){ public void drawTop(){
//draw schematic selection
if(mode == schematicSelect){ if(mode == schematicSelect){
drawSelection(lineStartX, lineStartY, lastLineX, lastLineY, Vars.maxSchematicSize); drawSelection(lineStartX, lineStartY, lastLineX, lastLineY, Vars.maxSchematicSize);
}else if(mode == rebuildSelect){
drawRebuildSelection(lineStartX, lineStartY, lastLineX, lastLineY);
} }
drawCommanded(); drawCommanded();
@@ -443,6 +454,11 @@ public class MobileInput extends InputHandler implements GestureListener{
//endregion //endregion
//region input events, overrides //region input events, overrides
@Override
public boolean isRebuildSelecting(){
return rebuildMode;
}
@Override @Override
protected int schemOriginX(){ protected int schemOriginX(){
Tmp.v1.setZero(); Tmp.v1.setZero();
@@ -496,7 +512,8 @@ public class MobileInput extends InputHandler implements GestureListener{
//call tap events //call tap events
if(pointer == 0 && !selecting){ if(pointer == 0 && !selecting){
if(schematicMode && block == null){ if(schematicMode && block == null){
mode = schematicSelect; mode = rebuildMode ? rebuildSelect : schematicSelect;
//engage schematic selection mode //engage schematic selection mode
int tileX = tileX(screenX); int tileX = tileX(screenX);
int tileY = tileY(screenY); int tileY = tileY(screenY);
@@ -546,6 +563,9 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
schematicMode = false; schematicMode = false;
mode = none; mode = none;
}else if(mode == rebuildSelect){
rebuildArea(lineStartX, lineStartY, lastLineX, lastLineY);
mode = none;
}else{ }else{
Tile tile = tileAt(screenX, screenY); Tile tile = tileAt(screenX, screenY);
@@ -780,11 +800,15 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
//stop select when not in schematic mode //stop select when not in schematic mode
if(!schematicMode && mode == schematicSelect){ if(!schematicMode && (mode == schematicSelect || mode == rebuildSelect)){
mode = none; mode = none;
} }
if(mode == schematicSelect){ if(!rebuildMode && mode == rebuildSelect){
mode = none;
}
if(mode == schematicSelect || mode == rebuildSelect){
lastLineX = rawTileX(); lastLineX = rawTileX();
lastLineY = rawTileY(); lastLineY = rawTileY();
autoPan(); autoPan();

View File

@@ -1,6 +1,7 @@
package mindustry.maps.generators; package mindustry.maps.generators;
import arc.math.geom.*; import arc.math.geom.*;
import mindustry.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.io.*; import mindustry.io.*;
@@ -16,7 +17,13 @@ public class FileMapGenerator implements WorldGenerator{
public final SectorPreset preset; public final SectorPreset preset;
public FileMapGenerator(String mapName, SectorPreset preset){ public FileMapGenerator(String mapName, SectorPreset preset){
this.map = maps != null ? maps.loadInternalMap(mapName) : null; //try to look for the prefixed map first, then the mod-specific one
this.map = maps != null ? maps.loadInternalMap(
preset.minfo.mod == null || Vars.tree.get("maps/" + mapName + "." + mapExtension).exists() ?
mapName :
mapName.substring(1 + preset.minfo.mod.name.length())
) : null;
this.preset = preset; this.preset = preset;
} }

View File

@@ -575,7 +575,7 @@ public class ContentParser{
if(!value.has("sector") || !value.get("sector").isNumber()) throw new RuntimeException("SectorPresets must have a sector number."); if(!value.has("sector") || !value.get("sector").isNumber()) throw new RuntimeException("SectorPresets must have a sector number.");
SectorPreset out = new SectorPreset(mod + "-" + name); SectorPreset out = new SectorPreset(mod + "-" + name, currentMod);
currentContent = out; currentContent = out;
read(() -> { read(() -> {

View File

@@ -51,7 +51,7 @@ public class ArcNetProvider implements NetProvider{
packetSpamLimit = Config.packetSpamLimit.num(); packetSpamLimit = Config.packetSpamLimit.num();
}); });
client = new Client(8192, 8192, new PacketSerializer()); client = new Client(8192, 16384, new PacketSerializer());
client.setDiscoveryPacket(packetSupplier); client.setDiscoveryPacket(packetSupplier);
client.addListener(new NetListener(){ client.addListener(new NetListener(){
@Override @Override

View File

@@ -5,6 +5,7 @@ import mindustry.ctype.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.maps.generators.*; import mindustry.maps.generators.*;
import mindustry.mod.Mods.*;
public class SectorPreset extends UnlockableContent{ public class SectorPreset extends UnlockableContent{
public FileMapGenerator generator; public FileMapGenerator generator;
@@ -36,11 +37,17 @@ public class SectorPreset extends UnlockableContent{
} }
/** Internal use only! */ /** Internal use only! */
public SectorPreset(String name){ public SectorPreset(String name, LoadedMod mod){
super(name); super(name);
this.minfo.mod = mod;
this.generator = new FileMapGenerator(name, this); this.generator = new FileMapGenerator(name, this);
} }
/** Internal use only! */
public SectorPreset(String name){
this(name, null);
}
public void initialize(Planet planet, int sector){ public void initialize(Planet planet, int sector){
this.planet = planet; this.planet = planet;
sector %= planet.sectors.size; sector %= planet.sectors.size;

View File

@@ -10,6 +10,7 @@ import arc.math.geom.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.ai.types.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.audio.*; import mindustry.audio.*;
import mindustry.content.*; import mindustry.content.*;
@@ -456,7 +457,8 @@ public class Weapon implements Cloneable{
lifeScl = bullet.scaleLife ? Mathf.clamp(Mathf.dst(bulletX, bulletY, mount.aimX, mount.aimY) / bullet.range) : 1f, lifeScl = bullet.scaleLife ? Mathf.clamp(Mathf.dst(bulletX, bulletY, mount.aimX, mount.aimY) / bullet.range) : 1f,
angle = angleOffset + shootAngle + Mathf.range(inaccuracy + bullet.inaccuracy); angle = angleOffset + shootAngle + Mathf.range(inaccuracy + bullet.inaccuracy);
mount.bullet = bullet.create(unit, unit.team, bulletX, bulletY, angle, -1f, (1f - velocityRnd) + Mathf.random(velocityRnd), lifeScl, null, mover, mount.aimX, mount.aimY); Entityc shooter = unit.controller() instanceof MissileAI ai ? ai.shooter : unit; //Pass the missile's shooter down to its bullets
mount.bullet = bullet.create(shooter, unit.team, bulletX, bulletY, angle, -1f, (1f - velocityRnd) + Mathf.random(velocityRnd), lifeScl, null, mover, mount.aimX, mount.aimY);
handleBullet(unit, mount, mount.bullet); handleBullet(unit, mount, mount.bullet);
if(!continuous){ if(!continuous){

View File

@@ -42,6 +42,14 @@ public class BaseDialog extends Dialog{
this(title, Core.scene.getStyle(DialogStyle.class)); this(title, Core.scene.getStyle(DialogStyle.class));
} }
/** Places the buttons as an overlay on top of the content. Used when the content can be scrolled through.*/
protected void makeButtonOverlay(){
clearChildren();
add(titleTable).growX().row();
stack(cont, buttons).grow();
buttons.bottom();
}
protected void onResize(Runnable run){ protected void onResize(Runnable run){
Events.on(ResizeEvent.class, event -> { Events.on(ResizeEvent.class, event -> {
if(isShown() && Core.scene.getDialog() == this){ if(isShown() && Core.scene.getDialog() == this){
@@ -55,11 +63,15 @@ public class BaseDialog extends Dialog{
closeOnBack(); closeOnBack();
} }
@Override public void addCloseButton(float width){
public void addCloseButton(){ buttons.defaults().size(width, 64f);
buttons.defaults().size(210f, 64f); buttons.button("@back", Icon.left, this::hide).size(width, 64f);
buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
addCloseListener(); addCloseListener();
} }
@Override
public void addCloseButton(){
addCloseButton(210f);
}
} }

View File

@@ -1,98 +1,16 @@
package mindustry.ui.dialogs; package mindustry.ui.dialogs;
import arc.*;
import arc.graphics.g2d.*;
import arc.scene.style.*;
import arc.scene.ui.*;
import arc.scene.ui.ImageButton.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.maps.*; import mindustry.maps.*;
import mindustry.ui.*;
public class CustomGameDialog extends BaseDialog{ public class CustomGameDialog extends MapListDialog{
private MapPlayDialog dialog = new MapPlayDialog(); private MapPlayDialog dialog = new MapPlayDialog();
public CustomGameDialog(){ public CustomGameDialog(){
super("@customgame"); super("@customgame", false);
addCloseButton();
shown(this::setup);
onResize(this::setup);
} }
void setup(){ @Override
clearChildren(); void showMap(Map map){
add(titleTable).growX().row(); dialog.show(map);
stack(cont, buttons).grow();
buttons.bottom();
cont.clear();
Table maps = new Table();
maps.marginBottom(55f).marginRight(-20f);
ScrollPane pane = new ScrollPane(maps);
pane.setFadeScrollBars(false);
int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(210)), 1);
float images = 146f;
ImageButtonStyle style = new ImageButtonStyle(){{
up = Styles.grayPanel;
down = Styles.flatOver;
over = Styles.flatOver;
disabled = Styles.none;
}};
int i = 0;
maps.defaults().width(170).fillY().top().pad(4f);
for(Map map : Vars.maps.all()){
if(i % maxwidth == 0){
maps.row();
}
ImageButton image = new ImageButton(new TextureRegion(map.safeTexture()), style);
image.margin(5);
image.top();
Image img = image.getImage();
img.remove();
image.row();
image.table(t -> {
t.left();
for(Gamemode mode : Gamemode.all){
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()) + "Small");
if(mode.valid(map) && Core.atlas.isFound(icon.getRegion())){
t.image(icon).size(16f).pad(4f);
}
}
}).left();
image.row();
image.add(map.name()).pad(1f).growX().wrap().left().get().setEllipsis(true);
image.row();
image.image(Tex.whiteui, Pal.gray).growX().pad(3).height(4f);
image.row();
image.add(img).size(images);
BorderImage border = new BorderImage(map.safeTexture(), 3f);
border.setScaling(Scaling.fit);
image.replaceImage(border);
image.clicked(() -> dialog.show(map));
maps.add(image);
i++;
}
if(Vars.maps.all().size == 0){
maps.add("@maps.none").pad(50);
}
cont.add(pane).grow();
} }
} }

View File

@@ -0,0 +1,155 @@
package mindustry.ui.dialogs;
import arc.*;
import arc.graphics.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.*;
import mindustry.game.EventType.*;
import mindustry.gen.*;
import mindustry.io.*;
import mindustry.maps.*;
import mindustry.ui.*;
import static mindustry.Vars.*;
public class EditorMapsDialog extends MapListDialog{
public EditorMapsDialog(){
super("@maps", true);
}
@Override
void buildButtons(){
buttons.button("@editor.newmap", Icon.add, () -> {
ui.showTextInput("@editor.newmap", "@editor.mapname", "", text -> {
Runnable show = () -> ui.loadAnd(() -> {
hide();
ui.editor.show();
editor.tags.put("name", text);
Events.fire(new MapMakeEvent());
});
if(maps.byName(text) != null){
ui.showErrorMessage("@editor.exists");
}else{
show.run();
}
});
}).size(210f, 64f);
buttons.button("@editor.importmap", Icon.upload, () -> {
platform.showFileChooser(true, mapExtension, file -> {
ui.loadAnd(() -> {
maps.tryCatchMapError(() -> {
if(MapIO.isImage(file)){
ui.showErrorMessage("@editor.errorimage");
return;
}
Map map = MapIO.createMap(file, true);
//when you attempt to import a save, it will have no name, so generate one
String name = map.tags.get("name", () -> {
String result = "unknown";
int number = 0;
while(maps.byName(result + number++) != null) ;
return result + number;
});
//this will never actually get called, but it remains just in case
if(name == null){
ui.showErrorMessage("@editor.errorname");
return;
}
Map conflict = maps.all().find(m -> m.name().equals(name));
if(conflict != null && !conflict.custom){
ui.showInfo(Core.bundle.format("editor.import.exists", name));
}else if(conflict != null){
ui.showConfirm("@confirm", Core.bundle.format("editor.overwrite.confirm", map.name()), () -> {
maps.tryCatchMapError(() -> {
maps.removeMap(conflict);
maps.importMap(map.file);
setup();
});
});
}else{
maps.importMap(map.file);
setup();
}
});
});
});
}).size(210f, 64f);
}
@Override
void showMap(Map map){
BaseDialog dialog = activeDialog = new BaseDialog("@editor.mapinfo");
dialog.addCloseButton();
float mapsize = Core.graphics.isPortrait() ? 160f : 300f;
Table table = dialog.cont;
table.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize);
table.table(Styles.black, desc -> {
desc.top();
Table t = new Table();
t.margin(6);
ScrollPane pane = new ScrollPane(t);
desc.add(pane).grow();
t.top();
t.defaults().padTop(10).left();
t.add("@editor.mapname").padRight(10).color(Color.gray).padTop(0);
t.row();
t.add(map.name()).growX().wrap().padTop(2);
t.row();
t.add("@editor.author").padRight(10).color(Color.gray);
t.row();
t.add(!map.custom && map.tags.get("author", "").isEmpty() ? "Anuke" : map.author()).growX().wrap().padTop(2);
t.row();
if(!map.tags.get("description", "").isEmpty()){
t.add("@editor.description").padRight(10).color(Color.gray).top();
t.row();
t.add(map.description()).growX().wrap().padTop(2);
}
}).height(mapsize).width(mapsize);
table.row();
table.button("@editor.openin", Icon.export, () -> {
try{
Vars.ui.editor.beginEditMap(map.file);
dialog.hide();
hide();
}catch(Exception e){
Log.err(e);
ui.showErrorMessage("@error.mapnotfound");
}
}).fillX().height(54f).marginLeft(10);
table.button(map.workshop && steam ? "@view.workshop" : "@delete", map.workshop && steam ? Icon.link : Icon.trash, () -> {
if(map.workshop && steam){
platform.viewListing(map);
}else{
ui.showConfirm("@confirm", Core.bundle.format("map.delete", map.name()), () -> {
maps.removeMap(map);
dialog.hide();
setup();
});
}
}).fillX().height(54f).marginLeft(10).disabled(!map.workshop && !map.custom);
dialog.show();
}
}

View File

@@ -45,6 +45,8 @@ public class JoinDialog extends BaseDialog{
public JoinDialog(){ public JoinDialog(){
super("@joingame"); super("@joingame");
makeButtonOverlay();
style = new TextButtonStyle(){{ style = new TextButtonStyle(){{
over = Styles.flatOver; over = Styles.flatOver;
font = Fonts.def; font = Fonts.def;
@@ -56,13 +58,21 @@ public class JoinDialog extends BaseDialog{
loadServers(); loadServers();
if(!steam) buttons.add().width(60f); //mobile players don't get information >:(
boolean infoButton = !steam && !mobile;
if(infoButton) buttons.add().width(60f);
buttons.add().growX().width(-1); buttons.add().growX().width(-1);
addCloseButton(); addCloseButton(mobile ? 190f : 210f);
buttons.button("@server.add", Icon.add, () -> {
renaming = null;
add.show();
});
buttons.add().growX().width(-1); buttons.add().growX().width(-1);
if(!steam) buttons.button("?", () -> ui.showInfo("@join.info")).size(60f, 64f); if(infoButton) buttons.button("?", () -> ui.showInfo("@join.info")).size(60f, 64f);
add = new BaseDialog("@joingame.title"); add = new BaseDialog("@joingame.title");
add.cont.add("@joingame.ip").padRight(5f).left(); add.cont.add("@joingame.ip").padRight(5f).left();
@@ -314,6 +324,8 @@ public class JoinDialog extends BaseDialog{
float w = targetWidth(); float w = targetWidth();
hosts.clear(); hosts.clear();
//since the buttons are an overlay, make room for that
hosts.marginBottom(70f);
section(steam ? "@servers.local.steam" : "@servers.local", local, false); section(steam ? "@servers.local.steam" : "@servers.local", local, false);
section("@servers.remote", remote, false); section("@servers.remote", remote, false);
@@ -344,25 +356,6 @@ public class JoinDialog extends BaseDialog{
cont.row(); cont.row();
cont.add(pane).width((w + 5) * columns() + 33).pad(0); cont.add(pane).width((w + 5) * columns() + 33).pad(0);
cont.row(); cont.row();
cont.buttonCenter("@server.add", Icon.add, () -> {
renaming = null;
add.show();
}).marginLeft(10).width(w).height(80f).update(button -> {
float pw = w;
float pad = 0f;
if(pane.getChildren().first().getPrefHeight() > pane.getHeight()){
pw = w + 30;
pad = 6;
}
var cell = ((Table)pane.parent).getCell(button);
if(!Mathf.equal(cell.minWidth(), pw)){
cell.width(pw);
cell.padLeft(pad);
pane.parent.invalidateHierarchy();
}
});
} }
void section(String label, Table servers, boolean eye){ void section(String label, Table servers, boolean eye){

View File

@@ -0,0 +1,230 @@
package mindustry.ui.dialogs;
import arc.*;
import arc.graphics.*;
import arc.scene.style.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.maps.*;
import mindustry.ui.*;
import static mindustry.Vars.*;
public abstract class MapListDialog extends BaseDialog{
BaseDialog activeDialog;
private String searchString;
private Seq<Gamemode> modes = new Seq<>();
private Table mapTable = new Table();
private TextField searchField;
private boolean
showBuiltIn = Core.settings.getBool("editorshowbuiltinmaps", true),
showCustom = Core.settings.getBool("editorshowcustommaps", true),
searchAuthor = Core.settings.getBool("editorsearchauthor", false),
searchDescription = Core.settings.getBool("editorsearchdescription", false),
displayType;
public MapListDialog(String title, boolean displayType){
super(title);
this.displayType = displayType;
buttons.remove();
addCloseListener();
shown(this::setup);
onResize(() -> {
if(activeDialog != null){
activeDialog.hide();
}
setup();
});
}
void buildButtons(){}
abstract void showMap(Map map);
void setup(){
makeButtonOverlay();
buttons.clearChildren();
searchString = null;
if(Core.graphics.isPortrait() && displayType){
buttons.button("@back", Icon.left, this::hide).size(210f * 2f, 64f).colspan(2);
buttons.row();
}else{
buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
}
buildButtons();
cont.clear();
rebuildMaps();
ScrollPane pane = new ScrollPane(mapTable);
pane.setFadeScrollBars(false);
pane.setScrollingDisabledX(true);
Table search = new Table();
search.image(Icon.zoom);
searchField = search.field("", t -> {
searchString = t.length() > 0 ? t.toLowerCase() : null;
rebuildMaps();
}).maxTextLength(50).growX().get();
searchField.setMessageText("@editor.search");
search.button(Icon.filter, Styles.emptyi, this::showMapFilters).tooltip("@editor.filters");
cont.add(search).growX();
cont.row();
cont.add(pane).padLeft(36f).uniformX().growY();
}
void rebuildMaps(){
mapTable.clear();
mapTable.marginRight(18f);
int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
float mapsize = 200f;
boolean noMapsShown = true;
int i = 0;
Seq<Map> mapList = showCustom ?
showBuiltIn ? maps.all() : maps.customMaps() :
showBuiltIn ? maps.defaultMaps() : null;
if(mapList != null){
for(Map map : mapList){
boolean invalid = false;
for(Gamemode mode : modes){
invalid |= !mode.valid(map);
}
if(invalid || (searchString != null
&& !Strings.stripColors(map.name()).toLowerCase().contains(searchString)
&& (!searchAuthor || !Strings.stripColors(map.author()).toLowerCase().contains(searchString))
&& (!searchDescription || !Strings.stripColors(map.description()).toLowerCase().contains(searchString)))){
continue;
}
noMapsShown = false;
if(i % maxwidth == 0){
mapTable.row();
}
TextButton button = mapTable.button("", Styles.grayt, () -> showMap(map)).width(mapsize).bottom().growY().pad(8).get();
button.clearChildren();
button.margin(9);
button.bottom();
//TODO hide in editor?
button.table(t -> {
t.left();
for(Gamemode mode : Gamemode.all){
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()) + "Small");
if(mode.valid(map) && Core.atlas.isFound(icon.getRegion())){
t.image(icon).size(16f).pad(4f);
}
}
}).left().row();
button.add(map.name()).width(mapsize - 18f).center().get().setEllipsis(true);
button.row();
button.image().growX().pad(4).color(Pal.gray);
button.row();
button.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize - 20f);
if(displayType){
button.row();
button.add(map.custom ? "@custom" : map.workshop ? "@workshop" : map.mod != null ? "[lightgray]" + map.mod.meta.displayName() : "@builtin").color(Color.gray).padTop(3);
}
i++;
}
}
if(noMapsShown){
mapTable.add("@maps.none");
}
}
void showMapFilters(){
activeDialog = new BaseDialog("@editor.filters");
activeDialog.addCloseButton();
activeDialog.cont.table(menu -> {
menu.add("@editor.filters.mode").width(150f).left();
menu.table(t -> {
for(Gamemode mode : Gamemode.all){
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()));
if(Core.atlas.isFound(icon.getRegion())){
t.button(icon, Styles.emptyTogglei, () -> {
if(modes.contains(mode)){
modes.remove(mode);
}else{
modes.add(mode);
}
rebuildMaps();
}).size(60f).checked(modes.contains(mode)).tooltip("@mode." + mode.name() + ".name");
}
}
}).padBottom(10f);
menu.row();
menu.add("@editor.filters.type").width(150f).left();
menu.table(Tex.button, t -> {
t.button("@custom", Styles.flatTogglet, () -> {
showCustom = !showCustom;
Core.settings.put("editorshowcustommaps", showCustom);
rebuildMaps();
}).size(150f, 60f).checked(showCustom);
t.button("@builtin", Styles.flatTogglet, () -> {
showBuiltIn = !showBuiltIn;
Core.settings.put("editorshowbuiltinmaps", showBuiltIn);
rebuildMaps();
}).size(150f, 60f).checked(showBuiltIn);
}).padBottom(10f);
menu.row();
menu.add("@editor.filters.search").width(150f).left();
menu.table(Tex.button, t -> {
t.button("@editor.filters.author", Styles.flatTogglet, () -> {
searchAuthor = !searchAuthor;
Core.settings.put("editorsearchauthor", searchAuthor);
rebuildMaps();
}).size(150f, 60f).checked(searchAuthor);
t.button("@editor.filters.description", Styles.flatTogglet, () -> {
searchDescription = !searchDescription;
Core.settings.put("editorsearchdescription", searchDescription);
rebuildMaps();
}).size(150f, 60f).checked(searchDescription);
});
});
activeDialog.show();
}
@Override
public Dialog show(){
super.show();
if(Core.app.isDesktop() && searchField != null){
Core.scene.setKeyboardFocus(searchField);
}
return this;
}
}

View File

@@ -1,332 +0,0 @@
package mindustry.ui.dialogs;
import arc.*;
import arc.graphics.*;
import arc.scene.style.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.io.*;
import mindustry.maps.*;
import mindustry.ui.*;
import static mindustry.Vars.*;
public class MapsDialog extends BaseDialog{
private BaseDialog dialog;
private String searchString;
private Seq<Gamemode> modes = new Seq<>();
private Table mapTable = new Table();
private TextField searchField;
private boolean showBuiltIn = Core.settings.getBool("editorshowbuiltinmaps", true);
private boolean showCustom = Core.settings.getBool("editorshowcustommaps", true);
private boolean searchAuthor = Core.settings.getBool("editorsearchauthor", false);
private boolean searchDescription = Core.settings.getBool("editorsearchdescription", false);
public MapsDialog(){
super("@maps");
buttons.remove();
addCloseListener();
shown(this::setup);
onResize(() -> {
if(dialog != null){
dialog.hide();
}
setup();
});
}
void setup(){
buttons.clearChildren();
searchString = null;
if(Core.graphics.isPortrait()){
buttons.button("@back", Icon.left, this::hide).size(210f * 2f, 64f).colspan(2);
buttons.row();
}else{
buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
}
buttons.button("@editor.newmap", Icon.add, () -> {
ui.showTextInput("@editor.newmap", "@editor.mapname", "", text -> {
Runnable show = () -> ui.loadAnd(() -> {
hide();
ui.editor.show();
editor.tags.put("name", text);
Events.fire(new MapMakeEvent());
});
if(maps.byName(text) != null){
ui.showErrorMessage("@editor.exists");
}else{
show.run();
}
});
}).size(210f, 64f);
buttons.button("@editor.importmap", Icon.upload, () -> {
platform.showFileChooser(true, mapExtension, file -> {
ui.loadAnd(() -> {
maps.tryCatchMapError(() -> {
if(MapIO.isImage(file)){
ui.showErrorMessage("@editor.errorimage");
return;
}
Map map = MapIO.createMap(file, true);
//when you attempt to import a save, it will have no name, so generate one
String name = map.tags.get("name", () -> {
String result = "unknown";
int number = 0;
while(maps.byName(result + number++) != null) ;
return result + number;
});
//this will never actually get called, but it remains just in case
if(name == null){
ui.showErrorMessage("@editor.errorname");
return;
}
Map conflict = maps.all().find(m -> m.name().equals(name));
if(conflict != null && !conflict.custom){
ui.showInfo(Core.bundle.format("editor.import.exists", name));
}else if(conflict != null){
ui.showConfirm("@confirm", Core.bundle.format("editor.overwrite.confirm", map.name()), () -> {
maps.tryCatchMapError(() -> {
maps.removeMap(conflict);
maps.importMap(map.file);
setup();
});
});
}else{
maps.importMap(map.file);
setup();
}
});
});
});
}).size(210f, 64f);
cont.clear();
rebuildMaps();
ScrollPane pane = new ScrollPane(mapTable);
pane.setFadeScrollBars(false);
Table search = new Table();
search.image(Icon.zoom);
searchField = search.field("", t -> {
searchString = t.length() > 0 ? t.toLowerCase() : null;
rebuildMaps();
}).maxTextLength(50).growX().get();
searchField.setMessageText("@editor.search");
search.button(Icon.filter, Styles.emptyi, this::showMapFilters).tooltip("@editor.filters");
cont.add(search).growX();
cont.row();
cont.add(pane).uniformX().growY();
cont.row();
cont.add(buttons).growX();
}
void rebuildMaps(){
mapTable.clear();
mapTable.marginRight(24);
int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1);
float mapsize = 200f;
boolean noMapsShown = true;
int i = 0;
Seq<Map> mapList = showCustom ?
showBuiltIn ? maps.all() : maps.customMaps() :
showBuiltIn ? maps.defaultMaps() : null;
if(mapList != null){
for(Map map : mapList){
boolean invalid = false;
for(Gamemode mode : modes){
invalid |= !mode.valid(map);
}
if(invalid || (searchString != null
&& !Strings.stripColors(map.name()).toLowerCase().contains(searchString)
&& (!searchAuthor || !Strings.stripColors(map.author()).toLowerCase().contains(searchString))
&& (!searchDescription || !Strings.stripColors(map.description()).toLowerCase().contains(searchString)))){
continue;
}
noMapsShown = false;
if(i % maxwidth == 0){
mapTable.row();
}
TextButton button = mapTable.button("", Styles.grayt, () -> showMapInfo(map)).width(mapsize).pad(8).get();
button.clearChildren();
button.margin(9);
button.add(map.name()).width(mapsize - 18f).center().get().setEllipsis(true);
button.row();
button.image().growX().pad(4).color(Pal.gray);
button.row();
button.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize - 20f);
button.row();
button.add(map.custom ? "@custom" : map.workshop ? "@workshop" : map.mod != null ? "[lightgray]" + map.mod.meta.displayName() : "@builtin").color(Color.gray).padTop(3);
i++;
}
}
if(noMapsShown){
mapTable.add("@maps.none");
}
}
void showMapFilters(){
dialog = new BaseDialog("@editor.filters");
dialog.addCloseButton();
dialog.cont.table(menu -> {
menu.add("@editor.filters.mode").width(150f).left();
menu.table(t -> {
for(Gamemode mode : Gamemode.all){
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()));
if(Core.atlas.isFound(icon.getRegion())){
t.button(icon, Styles.emptyTogglei, () -> {
if(modes.contains(mode)){
modes.remove(mode);
}else{
modes.add(mode);
}
rebuildMaps();
}).size(60f).checked(modes.contains(mode)).tooltip("@mode." + mode.name() + ".name");
}
}
}).padBottom(10f);
menu.row();
menu.add("@editor.filters.type").width(150f).left();
menu.table(Tex.button, t -> {
t.button("@custom", Styles.flatTogglet, () -> {
showCustom = !showCustom;
Core.settings.put("editorshowcustommaps", showCustom);
rebuildMaps();
}).size(150f, 60f).checked(showCustom);
t.button("@builtin", Styles.flatTogglet, () -> {
showBuiltIn = !showBuiltIn;
Core.settings.put("editorshowbuiltinmaps", showBuiltIn);
rebuildMaps();
}).size(150f, 60f).checked(showBuiltIn);
}).padBottom(10f);
menu.row();
menu.add("@editor.filters.search").width(150f).left();
menu.table(Tex.button, t -> {
t.button("@editor.filters.author", Styles.flatTogglet, () -> {
searchAuthor = !searchAuthor;
Core.settings.put("editorsearchauthor", searchAuthor);
rebuildMaps();
}).size(150f, 60f).checked(searchAuthor);
t.button("@editor.filters.description", Styles.flatTogglet, () -> {
searchDescription = !searchDescription;
Core.settings.put("editorsearchdescription", searchDescription);
rebuildMaps();
}).size(150f, 60f).checked(searchDescription);
});
});
dialog.show();
}
void showMapInfo(Map map){
dialog = new BaseDialog("@editor.mapinfo");
dialog.addCloseButton();
float mapsize = Core.graphics.isPortrait() ? 160f : 300f;
Table table = dialog.cont;
table.stack(new Image(map.safeTexture()).setScaling(Scaling.fit), new BorderImage(map.safeTexture()).setScaling(Scaling.fit)).size(mapsize);
table.table(Styles.black, desc -> {
desc.top();
Table t = new Table();
t.margin(6);
ScrollPane pane = new ScrollPane(t);
desc.add(pane).grow();
t.top();
t.defaults().padTop(10).left();
t.add("@editor.mapname").padRight(10).color(Color.gray).padTop(0);
t.row();
t.add(map.name()).growX().wrap().padTop(2);
t.row();
t.add("@editor.author").padRight(10).color(Color.gray);
t.row();
t.add(!map.custom && map.tags.get("author", "").isEmpty() ? "Anuke" : map.author()).growX().wrap().padTop(2);
t.row();
if(!map.tags.get("description", "").isEmpty()){
t.add("@editor.description").padRight(10).color(Color.gray).top();
t.row();
t.add(map.description()).growX().wrap().padTop(2);
}
}).height(mapsize).width(mapsize);
table.row();
table.button("@editor.openin", Icon.export, () -> {
try{
Vars.ui.editor.beginEditMap(map.file);
dialog.hide();
hide();
}catch(Exception e){
e.printStackTrace();
ui.showErrorMessage("@error.mapnotfound");
}
}).fillX().height(54f).marginLeft(10);
table.button(map.workshop && steam ? "@view.workshop" : "@delete", map.workshop && steam ? Icon.link : Icon.trash, () -> {
if(map.workshop && steam){
platform.viewListing(map);
}else{
ui.showConfirm("@confirm", Core.bundle.format("map.delete", map.name()), () -> {
maps.removeMap(map);
dialog.hide();
setup();
});
}
}).fillX().height(54f).marginLeft(10).disabled(!map.workshop && !map.custom);
dialog.show();
}
@Override
public Dialog show(){
super.show();
if(Core.app.isDesktop() && searchField != null){
Core.scene.setKeyboardFocus(searchField);
}
return this;
}
}

View File

@@ -184,7 +184,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
b.add(planet.localizedName).color(Pal.accent).style(Styles.outlineLabel); b.add(planet.localizedName).color(Pal.accent).style(Styles.outlineLabel);
b.row(); b.row();
b.image(new TextureRegionDrawable(tex)).grow().scaling(Scaling.fit); b.image(new TextureRegionDrawable(tex)).grow().scaling(Scaling.fit);
}, Styles.togglet, () -> selected[0] = planet).size(Core.app.isMobile() ? 220f : 320f).group(group); }, Styles.togglet, () -> selected[0] = planet).size(mobile ? 220f : 320f).group(group);
i ++; i ++;
} }
@@ -606,29 +606,42 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
t.label(() -> mode == select ? "@sectors.select" : "").style(Styles.outlineLabel).color(Pal.accent); t.label(() -> mode == select ? "@sectors.select" : "").style(Styles.outlineLabel).color(Pal.accent);
}), }),
buttons, buttons,
//planet selection
// planet selection
new Table(t -> { new Table(t -> {
t.top().left(); t.top().left();
if(content.planets().count(this::selectable) > 1){ ScrollPane pane = new ScrollPane(null, Styles.smallPane);
t.table(Tex.pane, pt -> { t.add(pane).colspan(2).row();
pt.margin(4f); Table starsTable = new Table(Styles.black);
for(int i = 0; i < content.planets().size; i++){ pane.setWidget(starsTable);
Planet planet = content.planets().get(i); pane.setScrollingDisabled(true, false);
if(selectable(planet)){
pt.button(planet.localizedName, Icon.icons.get(planet.icon + "Small", Icon.icons.get(planet.icon, Icon.commandRallySmall)), Styles.flatTogglet, () -> { int starCount = 0;
selected = null; for(Planet star : content.planets()){
launchSector = null; if(star.solarSystem != star || !content.planets().contains(p -> p.solarSystem == star && selectable(p))) continue;
if(state.planet != planet){
newPresets.clear(); starCount++;
state.planet = planet; if(starCount > 1) starsTable.add(star.localizedName).padLeft(10f).padBottom(10f).padTop(10f).left().width(190f).row();
rebuildExpand(); Table planetTable = new Table();
} planetTable.margin(4f); //less padding
settings.put("lastplanet", planet.name); starsTable.add(planetTable).left().row();
}).width(190).height(40).growX().update(bb -> bb.setChecked(state.planet == planet)).with(w -> w.marginLeft(10f)).get().getChildren().get(1).setColor(planet.iconColor); for(Planet planet : content.planets()){
pt.row(); if(planet.solarSystem == star && selectable(planet)){
} Button planetButton = planetTable.button(planet.localizedName, Icon.icons.get(planet.icon + "Small", Icon.icons.get(planet.icon, Icon.commandRallySmall)), Styles.flatTogglet, () -> {
selected = null;
launchSector = null;
if(state.planet != planet){
newPresets.clear();
state.planet = planet;
rebuildExpand();
}
settings.put("lastplanet", planet.name);
}).width(200).height(40).update(bb -> bb.setChecked(state.planet == planet)).with(w -> w.marginLeft(10f)).get();
planetButton.getChildren().get(1).setColor(planet.iconColor);
planetButton.setColor(planet.iconColor);
planetTable.background(Tex.pane).row();
} }
}); }
} }
}), }),

View File

@@ -174,7 +174,7 @@ public class HintsFragment{
payloadDrop(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()), payloadDrop(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().any(), () -> player.unit() instanceof Payloadc p && p.payloads().isEmpty()),
waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0), waveFire(() -> Groups.fire.size() > 0 && Blocks.wave.unlockedNow(), () -> indexer.getFlagged(state.rules.defaultTeam, BlockFlag.extinguisher).size > 0),
generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)), generator(() -> control.input.block == Blocks.combustionGenerator, () -> ui.hints.placedBlocks.contains(Blocks.combustionGenerator)),
rebuildSelect(visibleDesktop, () -> state.rules.defaultTeam.data().plans.size >= 10, () -> Core.input.keyDown(Binding.rebuild_select)), rebuildSelect(() -> state.rules.defaultTeam.data().plans.size >= 10, () -> control.input.isRebuildSelecting()),
guardian(() -> state.boss() != null && isSerpulo() && state.boss().armor >= 4, () -> state.boss() == null), guardian(() -> state.boss() != null && isSerpulo() && state.boss().armor >= 4, () -> state.boss() == null),
factoryControl(() -> !(state.isCampaign() && state.rules.sector.preset == SectorPresets.onset) && factoryControl(() -> !(state.isCampaign() && state.rules.sector.preset == SectorPresets.onset) &&
state.rules.defaultTeam.data().getBuildings(Blocks.tankFabricator).size + state.rules.defaultTeam.data().getBuildings(Blocks.groundFactory).size > 0, () -> ui.hints.events.contains("factorycontrol")), state.rules.defaultTeam.data().getBuildings(Blocks.tankFabricator).size + state.rules.defaultTeam.data().getBuildings(Blocks.groundFactory).size > 0, () -> ui.hints.events.contains("factorycontrol")),

View File

@@ -77,10 +77,12 @@ public class Build{
//auto-rotate the block to the correct orientation and bail out //auto-rotate the block to the correct orientation and bail out
if(tile.team() == team && tile.block == result && tile.build != null && tile.block.quickRotate){ if(tile.team() == team && tile.block == result && tile.build != null && tile.block.quickRotate){
if(unit != null && unit.getControllerName() != null) tile.build.lastAccessed = unit.getControllerName(); if(unit != null && unit.getControllerName() != null) tile.build.lastAccessed = unit.getControllerName();
int previous = tile.build.rotation;
tile.build.rotation = Mathf.mod(rotation, 4); tile.build.rotation = Mathf.mod(rotation, 4);
tile.build.updateProximity(); tile.build.updateProximity();
tile.build.noSleep(); tile.build.noSleep();
Fx.rotateBlock.at(tile.build.x, tile.build.y, tile.build.block.size); Fx.rotateBlock.at(tile.build.x, tile.build.y, tile.build.block.size);
Events.fire(new BuildRotateEvent(tile.build, unit, previous));
return; return;
} }
@@ -169,6 +171,10 @@ public class Build{
return false; return false;
} }
if((type.isFloor() && tile.floor() == type) || (type.isOverlay() && tile.overlay() == type)){
return false;
}
if(!type.canPlaceOn(tile, team, rotation)){ if(!type.canPlaceOn(tile, team, rotation)){
return false; return false;
} }

View File

@@ -303,7 +303,9 @@ public class Tile implements Position, QuadTreeObject, Displayable{
public void setFloorUnder(Floor floor){ public void setFloorUnder(Floor floor){
Block overlay = this.overlay; Block overlay = this.overlay;
setFloor(floor); setFloor(floor);
setOverlay(overlay); if(this.overlay != overlay){
setOverlay(overlay);
}
} }
/** Sets the block to air. */ /** Sets the block to air. */

View File

@@ -20,6 +20,7 @@ import mindustry.graphics.*;
import mindustry.logic.*; import mindustry.logic.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.environment.*;
import mindustry.world.blocks.storage.CoreBlock.*; import mindustry.world.blocks.storage.CoreBlock.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
@@ -72,7 +73,15 @@ public class ConstructBlock extends Block{
float healthf = tile.build == null ? 1f : tile.build.healthf(); float healthf = tile.build == null ? 1f : tile.build.healthf();
Seq<Building> prev = tile.build instanceof ConstructBuild co ? co.prevBuild : null; Seq<Building> prev = tile.build instanceof ConstructBuild co ? co.prevBuild : null;
tile.setBlock(block, team, rotation); if(block instanceof OverlayFloor overlay){
tile.setOverlay(overlay);
tile.setBlock(Blocks.air);
}else if(block instanceof Floor floor){
tile.setFloorUnder(floor);
tile.setBlock(Blocks.air);
}else{
tile.setBlock(block, team, rotation);
}
if(tile.build != null){ if(tile.build != null){
tile.build.health = block.health * healthf; tile.build.health = block.health * healthf;

View File

@@ -468,10 +468,10 @@ public class Turret extends ReloadTurret{
target = Units.bestEnemy(team, x, y, range, e -> !e.dead() && !e.isGrounded() && unitFilter.get(e), unitSort); target = Units.bestEnemy(team, x, y, range, e -> !e.dead() && !e.isGrounded() && unitFilter.get(e), unitSort);
}else{ }else{
target = Units.bestTarget(team, x, y, range, e -> !e.dead() && unitFilter.get(e) && (e.isGrounded() || targetAir) && (!e.isGrounded() || targetGround), b -> targetGround && buildingFilter.get(b), unitSort); target = Units.bestTarget(team, x, y, range, e -> !e.dead() && unitFilter.get(e) && (e.isGrounded() || targetAir) && (!e.isGrounded() || targetGround), b -> targetGround && buildingFilter.get(b), unitSort);
}
if(target == null && canHeal()){ if(target == null && canHeal()){
target = Units.findAllyTile(team, x, y, range, b -> b.damaged() && b != this); target = Units.findAllyTile(team, x, y, range, b -> b.damaged() && b != this);
}
} }
} }

View File

@@ -9,14 +9,16 @@ import mindustry.gen.*;
import mindustry.world.*; import mindustry.world.*;
public class DrawPistons extends DrawBlock{ public class DrawPistons extends DrawBlock{
public float sinMag = 4f, sinScl = 6f, sinOffset = 50f, sideOffset = 0f, lenOffset = -1f, angleOffset = 0f; public float sinMag = 4f, sinScl = 6f, sinOffset = 50f, sideOffset = 0f, lenOffset = -1f, horiOffset = 0f, angleOffset = 0f;
public int sides = 4; public int sides = 4;
public String suffix = "-piston"; public String suffix = "-piston";
public TextureRegion region1, region2, regiont; public TextureRegion region1, region2, regiont, iconRegion;
@Override @Override
public void drawPlan(Block block, BuildPlan plan, Eachable<BuildPlan> list){ public void drawPlan(Block block, BuildPlan plan, Eachable<BuildPlan> list){
if(iconRegion.found()){
Draw.rect(iconRegion, plan.drawx(), plan.drawy());
}
} }
@Override @Override
@@ -32,7 +34,8 @@ public class DrawPistons extends DrawBlock{
Draw.yscl = -1f; Draw.yscl = -1f;
} }
Draw.rect(reg, build.x + Angles.trnsx(angle, len), build.y + Angles.trnsy(angle, len), angle); Tmp.v1.trns(angle, len, -horiOffset);
Draw.rect(reg, build.x + Tmp.v1.x, build.y + Tmp.v1.y, angle);
Draw.yscl = 1f; Draw.yscl = 1f;
} }
@@ -45,5 +48,11 @@ public class DrawPistons extends DrawBlock{
region1 = Core.atlas.find(block.name + suffix + "0", block.name + suffix); region1 = Core.atlas.find(block.name + suffix + "0", block.name + suffix);
region2 = Core.atlas.find(block.name + suffix + "1", block.name + suffix); region2 = Core.atlas.find(block.name + suffix + "1", block.name + suffix);
regiont = Core.atlas.find(block.name + suffix + "-t"); regiont = Core.atlas.find(block.name + suffix + "-t");
iconRegion = Core.atlas.find(block.name + suffix + "-icon");
}
@Override
public TextureRegion[] icons(Block block){
return new TextureRegion[]{iconRegion};
} }
} }

View File

@@ -25,4 +25,4 @@ org.gradle.caching=true
#used for slow jitpack builds; TODO see if this actually works #used for slow jitpack builds; TODO see if this actually works
org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.socketTimeout=100000
org.gradle.internal.http.connectionTimeout=100000 org.gradle.internal.http.connectionTimeout=100000
archash=77461f1c82 archash=a0bdca954b