Compare commits

..

44 Commits
v114.2 ... v115

Author SHA1 Message Date
Anuken
bbc8c05f93 Merge pull request #3354 from Prosta4okua/master
[Bundle][RU] actual L10n
2020-11-19 10:39:15 -05:00
Anuken
bfbb082fd8 Merge pull request #3393 from Prosta4okua/patch-8
Ukrainian translation
2020-11-19 10:37:05 -05:00
Anuken
89ef2ac4d3 Naval research requirements for final sector 2020-11-19 10:23:46 -05:00
Anuken
506175212c Merge remote-tracking branch 'origin/master' 2020-11-19 10:14:49 -05:00
Anuken
b57b1966a7 Switched to ALSA Soloud backend / Fixed sound muffling at start 2020-11-19 10:14:44 -05:00
Anuken
08a50edb23 Merge pull request #3456 from DeltaNedas/mapsize
add @mapx/y to logic processor
2020-11-19 10:12:32 -05:00
Anuken
95c242a2e1 Fixed final sector missing waves / Fixed audio not working on Android 2020-11-19 09:43:15 -05:00
Felix Corvus
49a1a0b768 5 new lines; 1 line changed
New:

- indev.campaign
- launch.from
- sector.planetaryTerminal.name
- block.interplanetary-accelerator.name
- block.interplanetary-accelerator.description

Changed:

- sector.extractionOutpost.name
2020-11-19 17:43:08 +03:00
DeltaNedas
a44ef1f063 wh 2020-11-19 07:10:51 +00:00
Anuken
72d5a8a768 Added "Launching From" info 2020-11-18 20:05:45 -05:00
Anuken
8692639e62 Fixed foreshadow coolant stat roundoff error 2020-11-18 19:08:26 -05:00
Anuken
1ef264d560 Added final campaign map (WIP, untested) 2020-11-18 18:58:54 -05:00
Anuken
63d4428527 Fixed #3453 2020-11-18 18:29:31 -05:00
DeltaNedas
4beca5e07d add @mapx/y to logic processor 2020-11-18 23:22:11 +00:00
Anuken
2758e65e19 Fixed typo 2020-11-18 13:30:35 -05:00
Anuken
129d76ad7e Fixed #3449 2020-11-18 13:20:23 -05:00
Anuken
f4a7288633 Fixed #3447 2020-11-18 09:26:31 -05:00
Felix Corvus
1684c04e52 RU L10n Android changelog 29713 2020-11-18 14:04:44 +03:00
Félix Córvus
ece615e764 RU L10n Android short description 2020-11-18 13:49:28 +03:00
Felix Corvus
8b48ef4f92 3 changed lines
- stats
- sector.curcapture
- sector.fungalPass.description
2020-11-18 13:15:08 +03:00
Felix Corvus
0ee8c2362f 18 new lines; 2 changed lines; 3 removed lines
New:

- gameover.disconnect
- gameover.waiting
- stats
- showui
- wave.enemycores
- wave.enemycore
- requirement.produce
- sectors.export
- sectors.time
- sectors.threat
- sectors.wave
- sector.curcapture
- sector.attacked
- sector.lost
- sector.captured
- planets
- sector.extractionOutpost.name
- block.resupply-point.description

Changed:

- indev.popup
- item.scrap.description

Removed:

- bestwave
- sector.crags.name
Various notes & todos
2020-11-18 11:51:13 +03:00
Anuken
adc7b30eab Limited all logic strings/symbols to 30 characters 2020-11-17 21:01:25 -05:00
Anuken
527be41e32 Merged Unit & Builder components / Cleanup 2020-11-17 19:40:18 -05:00
Anuken
8280166485 Cleanup 2020-11-17 16:06:02 -05:00
Anuken
e453c6033a Cleanup 2020-11-17 15:05:24 -05:00
Prosta4okua
949ad79ade Update bundle_uk_UA.properties 2020-11-17 20:48:01 +02:00
Prosta4okua
daabdf486f Update bundle_uk_UA.properties 2020-11-17 20:40:27 +02:00
Prosta4okua
8b50bb68e7 Update bundle_uk_UA.properties 2020-11-17 20:33:05 +02:00
Prosta4okua
bd654fda76 Update bundle_uk_UA.properties 2020-11-17 20:29:26 +02:00
Anuken
40ae2e64c8 Merge remote-tracking branch 'origin/master' 2020-11-17 11:23:54 -05:00
Anuken
78ae6dde4f Fixed deconstruction area not being queued [Mobile] 2020-11-17 11:23:50 -05:00
Anuken
2071bad22d Merge pull request #3426 from MEEPofFaith/continuous-weapon-recoil
Begin reloading continuous weapons  after the bullet finishes.
2020-11-17 11:05:17 -05:00
MEEP of Faith
c72a9166a6 ;) 2020-11-16 16:22:38 -08:00
MEEP of Faith
ffca824474 Begin reloading continuous weapons after the bullet finishes. 2020-11-16 16:11:36 -08:00
Prosta4okua
dc35e61c3f Merge pull request #25 from summetdev/patch-8
content.sector.name
2020-11-15 02:39:07 +02:00
Antsiferov Andrew
d94765f470 content.sector.name 2020-11-15 01:09:34 +03:00
Prosta4okua
4a25063a29 Update bundle_uk_UA.properties 2020-11-14 15:50:53 +02:00
Prosta4okua
6b2ba8b432 Update bundle_uk_UA.properties 2020-11-14 15:48:59 +02:00
Prosta4okua
6753ab7c6e Update bundle_uk_UA.properties 2020-11-14 15:33:53 +02:00
Felix Corvus
dbc446f400 11 new lines
New:
threat.low
threat.medium
threat.high
threat.extreme
threat.eradication
sector.biomassFacility.name
sector.windsweptIslands.name
stat.weapons
stat.bullet
bullet.sapping
bullet.healpercent
2020-11-14 12:20:28 +03:00
Prosta4okua
ea41e38706 Оновлення
Залишилось перевіти десь зо 30 рядків
2020-11-13 23:59:24 +02:00
Vanguard
4a1300f789 1 changed line
mods.reloadexit
2020-11-12 21:48:39 +03:00
Prosta4okua
c263a1e52f Добридень 2020-11-11 21:58:39 +02:00
Vanguard
8c99a5cce0 1 changed line
sector.impact0078.name
2020-11-11 21:09:04 +03:00
92 changed files with 9760 additions and 9227 deletions

View File

@@ -29,7 +29,7 @@ script:
- cd ../Mindustry - cd ../Mindustry
deploy: deploy:
- provider: releases - provider: releases
skip_cleanup: true cleanup: false
draft: false draft: false
api_key: api_key:
secure: Cv5wFtWt62/A24EvSEQvMow7gKPbZ3oATEFPuSghhB2TQz1dA40Zee3Qvk4LFlpLrhYo4K0ZSczCZRGpR+hCd8+Dpww52bheYEvWuh3ZQfvu/fXtEx2j5PwP1qMpmIgSxETV/gkD7l9FImdh0VzktYiAvQfmi0bEocG9/D4QwjFpNat7iwBdcMiw1MvAygpdIWRsjiw0RKlB2mWarmoHhQ7Gu7qlU3j50uaEvcrtmU0pBUPggNQwQRv32i9NPvNFxrqqlUjDLIS8JFea99zCkp8BwYqbEvBIMzd+Qip1/stLJJA3+cDUClbsDtg8rAVetzpOrdLEEBmqShFe5MDl2yEHcsgpN9CFsyTaUfvB3P3rVjizvycMm42IsUkXQiarm5xTQ/TIA8Rd8AHiSKuweNCg1Fd5SFaRtKy8JVLXuxyfUccmyje6hhz2L4lS2Wfj3mAG7sqZUCXhWP79EKdGkiPOjKv4CwXEKmuH3BMVqPlNUZJr9Eg3sV1FG0h2l+MVOOnR635qdUbb49sYojYxVruMLX0BH1c4ZCu230m8CUoWA1Em1QNI75ya7+9Y5T6AsgWDVpBvdUo9fWNbdp+VQ0GskFQsJD5wtnxbcbHeFiERAgGBm7z6qt9u9LrQpBH+dsW52ADvYsu3L4nQEa+sdMHwTTwmGY+iUvsxu0DqxGg= secure: Cv5wFtWt62/A24EvSEQvMow7gKPbZ3oATEFPuSghhB2TQz1dA40Zee3Qvk4LFlpLrhYo4K0ZSczCZRGpR+hCd8+Dpww52bheYEvWuh3ZQfvu/fXtEx2j5PwP1qMpmIgSxETV/gkD7l9FImdh0VzktYiAvQfmi0bEocG9/D4QwjFpNat7iwBdcMiw1MvAygpdIWRsjiw0RKlB2mWarmoHhQ7Gu7qlU3j50uaEvcrtmU0pBUPggNQwQRv32i9NPvNFxrqqlUjDLIS8JFea99zCkp8BwYqbEvBIMzd+Qip1/stLJJA3+cDUClbsDtg8rAVetzpOrdLEEBmqShFe5MDl2yEHcsgpN9CFsyTaUfvB3P3rVjizvycMm42IsUkXQiarm5xTQ/TIA8Rd8AHiSKuweNCg1Fd5SFaRtKy8JVLXuxyfUccmyje6hhz2L4lS2Wfj3mAG7sqZUCXhWP79EKdGkiPOjKv4CwXEKmuH3BMVqPlNUZJr9Eg3sV1FG0h2l+MVOOnR635qdUbb49sYojYxVruMLX0BH1c4ZCu230m8CUoWA1Em1QNI75ya7+9Y5T6AsgWDVpBvdUo9fWNbdp+VQ0GskFQsJD5wtnxbcbHeFiERAgGBm7z6qt9u9LrQpBH+dsW52ADvYsu3L4nQEa+sdMHwTTwmGY+iUvsxu0DqxGg=

View File

@@ -1,10 +1,13 @@
#Maps entity names to IDs. Autogenerated. #Maps entity names to IDs. Autogenerated.
alpha=0 alpha=0
arkyid=29
atrax=1 atrax=1
beta=30
block=2 block=2
corvus=24 corvus=24
flare=3 flare=3
gamma=31
mace=4 mace=4
mega=5 mega=5
mindustry.entities.comp.BuildingComp=6 mindustry.entities.comp.BuildingComp=6
@@ -26,6 +29,8 @@ oct=26
poly=18 poly=18
pulsar=19 pulsar=19
quad=23 quad=23
quasar=32
risso=20 risso=20
spiroct=21 spiroct=21
toxopid=33
vela=25 vela=25

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{version:3,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:baseRotation,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{version:4,fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

View File

@@ -0,0 +1 @@
{fields:[{name:ammo,type:float},{name:armor,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue<mindustry.entities.units.BuildPlan>},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq<mindustry.entities.units.StatusEntry>},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:x,type:float},{name:y,type:float}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

View File

@@ -10,7 +10,7 @@ link.dev-builds.description = Unstable development builds
link.trello.description = Official Trello board for planned features link.trello.description = Official Trello board for planned features
link.itch.io.description = itch.io page with PC downloads link.itch.io.description = itch.io page with PC downloads
link.google-play.description = Google Play store listing link.google-play.description = Google Play store listing
link.f-droid.description = F-Droid catalogue listing link.f-droid.description = F-Droid listing
link.wiki.description = Official Mindustry wiki link.wiki.description = Official Mindustry wiki
link.suggestions.description = Suggest new features link.suggestions.description = Suggest new features
linkfail = Failed to open link!\nThe URL has been copied to your clipboard. linkfail = Failed to open link!\nThe URL has been copied to your clipboard.
@@ -24,6 +24,7 @@ highscore = [accent]New highscore!
copied = Copied. copied = Copied.
indev.popup = [accent]v6[] is currently in [accent]beta[].\n[lightgray]This means:[]\n[scarlet]- The campaign is unfinished[]\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[]. indev.popup = [accent]v6[] is currently in [accent]beta[].\n[lightgray]This means:[]\n[scarlet]- The campaign is unfinished[]\n- Everything you see is subject to change or removal.\n\nReport bugs or crashes on [accent]Github[].
indev.notready = This part of the game isn't ready yet indev.notready = This part of the game isn't ready yet
indev.campaign = [accent]You've reached the end of the campaign![]\n\nThis is as far as the content goes. Interplanetary travel will be added in future updates.
load.sound = Sounds load.sound = Sounds
load.map = Maps load.map = Maps
@@ -504,6 +505,7 @@ loadout = Loadout
resources = Resources resources = Resources
bannedblocks = Banned Blocks bannedblocks = Banned Blocks
addall = Add All addall = Add All
launch.from = Launching From: [accent]{0}
launch.destination = Destination: {0} launch.destination = Destination: {0}
configure.invalid = Amount must be a number between 0 and {0}. configure.invalid = Amount must be a number between 0 and {0}.
zone.unlocked = [lightgray]{0} unlocked. zone.unlocked = [lightgray]{0} unlocked.
@@ -562,10 +564,8 @@ threat.eradication = Eradication
planets = Planets planets = Planets
planet.serpulo.name = Serpulo planet.serpulo.name = Serpulo
#TODO better name
planet.sun.name = Sun planet.sun.name = Sun
#NOTE TO TRANSLATORS: don't bother editing these, they'll be removed and/or rewritten anyway
sector.impact0078.name = Impact 0078 sector.impact0078.name = Impact 0078
sector.groundZero.name = Ground Zero sector.groundZero.name = Ground Zero
sector.craters.name = The Craters sector.craters.name = The Craters
@@ -581,9 +581,7 @@ sector.fungalPass.name = Fungal Pass
sector.biomassFacility.name = Biomass Synthesis Facility sector.biomassFacility.name = Biomass Synthesis Facility
sector.windsweptIslands.name = Windswept Islands sector.windsweptIslands.name = Windswept Islands
sector.extractionOutpost.name = Extraction Outpost sector.extractionOutpost.name = Extraction Outpost
sector.planetaryTerminal.name = Planetary Launch Terminal
#unused
#sector.crags.name = Crags
sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on. sector.groundZero.description = The optimal location to begin once more. Low enemy threat. Few resources.\nGather as much lead and copper as possible.\nMove on.
sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders. sector.frozenForest.description = Even here, closer to mountains, the spores have spread. The frigid temperatures cannot contain them forever.\n\nBegin the venture into power. Build combustion generators. Learn to use menders.
@@ -1217,6 +1215,7 @@ block.overdrive-dome.name = Overdrive Dome
block.block-forge.name = Block Forge block.block-forge.name = Block Forge
block.block-loader.name = Block Loader block.block-loader.name = Block Loader
block.block-unloader.name = Block Unloader block.block-unloader.name = Block Unloader
block.interplanetary-accelerator.name = Interplanetary Accelerator
block.switch.name = Switch block.switch.name = Switch
block.micro-processor.name = Micro Processor block.micro-processor.name = Micro Processor
@@ -1278,11 +1277,13 @@ item.spore-pod.description = Used for conversion into oil, explosives and fuel.
item.spore-pod.details = Spores. Likely a synthetic life form. Emit gases toxic to other biological life. Extremely invasive. Highly flammable in certain conditions. item.spore-pod.details = Spores. Likely a synthetic life form. Emit gases toxic to other biological life. Extremely invasive. Highly flammable in certain conditions.
item.blast-compound.description = Used in bombs and explosive ammunition. item.blast-compound.description = Used in bombs and explosive ammunition.
item.pyratite.description = Used in incendiary weapons and combustion-fueled generators. item.pyratite.description = Used in incendiary weapons and combustion-fueled generators.
liquid.water.description = Used for cooling machines and waste processing. liquid.water.description = Used for cooling machines and waste processing.
liquid.slag.description = Refined in separators into constituent metals, or sprayed at enemies as a weapon. liquid.slag.description = Refined in separators into constituent metals, or sprayed at enemies as a weapon.
liquid.oil.description = Used in advanced material production and as incendiary ammunition. liquid.oil.description = Used in advanced material production and as incendiary ammunition.
liquid.cryofluid.description = Used as coolant in reactors, turrets and factories. liquid.cryofluid.description = Used as coolant in reactors, turrets and factories.
block.resupply-point.description = Resupplies nearby units with copper ammunition. Not compatible with units that require battery power.
block.armored-conveyor.description = Moves items forward. Does not accept inputs from the sides. block.armored-conveyor.description = Moves items forward. Does not accept inputs from the sides.
block.illuminator.description = Emits light. block.illuminator.description = Emits light.
block.message.description = Stores a message for communication between allies. block.message.description = Stores a message for communication between allies.
@@ -1425,6 +1426,7 @@ block.memory-cell.description = Stores information for a logic processor.
block.memory-bank.description = Stores information for a logic processor. High capacity. block.memory-bank.description = Stores information for a logic processor. High capacity.
block.logic-display.description = Displays arbitrary graphics from a logic processor. block.logic-display.description = Displays arbitrary graphics from a logic processor.
block.large-logic-display.description = Displays arbitrary graphics from a logic processor. block.large-logic-display.description = Displays arbitrary graphics from a logic processor.
block.interplanetary-accelerator.description = A massive electromagnetic railgun tower. Accelerates cores to escape velocity for interplanetary deployment.
unit.dagger.description = Fires standard bullets at all nearby enemies. unit.dagger.description = Fires standard bullets at all nearby enemies.
unit.mace.description = Fires streams of flame at all nearby enemies. unit.mace.description = Fires streams of flame at all nearby enemies.
@@ -1452,7 +1454,7 @@ unit.mega.description = Automatically repairs damaged structures. Capable of car
unit.quad.description = Drops large bombs on ground targets, repairing allied structures and damaging enemies. Capable of carrying medium-sized ground units. unit.quad.description = Drops large bombs on ground targets, repairing allied structures and damaging enemies. Capable of carrying medium-sized ground units.
unit.oct.description = Protects nearby allies with its regenerating shield. Capable of carrying most ground units. unit.oct.description = Protects nearby allies with its regenerating shield. Capable of carrying most ground units.
unit.risso.description = Fires a barrage of missiles and bullets at all nearby enemies. unit.risso.description = Fires a barrage of missiles and bullets at all nearby enemies.
unit.minke.description = Fires incendiary shells and standard bullets at nearby ground targets. unit.minke.description = Fires shells and standard bullets at nearby ground targets.
unit.bryde.description = Fires long-range artillery shells and missiles at enemies. unit.bryde.description = Fires long-range artillery shells and missiles at enemies.
unit.sei.description = Fires a barrage of missiles and armor-piercing bullets at enemies. unit.sei.description = Fires a barrage of missiles and armor-piercing bullets at enemies.
unit.omura.description = Fires a long-range piercing railgun bolt at enemies. Constructs flare units. unit.omura.description = Fires a long-range piercing railgun bolt at enemies. Constructs flare units.

View File

@@ -17,11 +17,14 @@ linkfail = Не удалось открыть ссылку!\nURL-адрес бы
screenshot = Скриншот сохранён в {0} screenshot = Скриншот сохранён в {0}
screenshot.invalid = Карта слишком большая, возможно, не хватает памяти для скриншота. screenshot.invalid = Карта слишком большая, возможно, не хватает памяти для скриншота.
gameover = Игра окончена gameover = Игра окончена
gameover.disconnect = Отключение
gameover.pvp = [accent]{0}[] команда победила! gameover.pvp = [accent]{0}[] команда победила!
gameover.waiting = [accent]Ожидание следующей карты...
highscore = [accent]Новый рекорд! highscore = [accent]Новый рекорд!
copied = Скопировано. copied = Скопировано.
indev.popup = [accent]v6[] находится на стадии [accent]beta[].\n[lightgray]Это означает следующее:[]\n[scarlet]- Кампания не завершена[]\n- Звуки и музыка не готовы/отсутствуют\n- Всё, что вы видите, может быть изменено или удалено.\n\nСообщайте о багах и вылетах на [accent]GitHub[]. indev.popup = [accent]v6[] находится на стадии [accent]beta[].\n[lightgray]Это означает следующее:[]\n[scarlet]- Кампания не завершена[]\n- Всё, что вы видите, может быть изменено или удалено.\n\nСообщайте о багах и вылетах на [accent]GitHub[].
indev.notready = Эта часть игры ещё не готова indev.notready = Эта часть игры ещё не готова
indev.campaign = [accent]Вы достигли конца кампании![]\n\nЭто всё что предоставляет контент. Межпланетные путешествия будут добавлены в будущих обновлениях.
load.sound = Звуки load.sound = Звуки
load.map = Карты load.map = Карты
@@ -57,6 +60,7 @@ schematic.rename = Переименовать схему
schematic.info = {0}x{1}, {2} блоков schematic.info = {0}x{1}, {2} блоков
schematic.disabled = [scarlet]Схемы отключены[]\nНа этой [accent]карте[] или [accent]сервере запрещено использование схем. schematic.disabled = [scarlet]Схемы отключены[]\nНа этой [accent]карте[] или [accent]сервере запрещено использование схем.
stats = Статистика
stat.wave = Волн отражено:[accent] {0} stat.wave = Волн отражено:[accent] {0}
stat.enemiesDestroyed = Врагов уничтожено:[accent] {0} stat.enemiesDestroyed = Врагов уничтожено:[accent] {0}
stat.built = Строений построено:[accent] {0} stat.built = Строений построено:[accent] {0}
@@ -107,7 +111,7 @@ mods.guide = Руководство по модам
mods.report = Доложить об ошибке mods.report = Доложить об ошибке
mods.openfolder = Открыть папку с модификациями mods.openfolder = Открыть папку с модификациями
mods.reload = Перезагрузить mods.reload = Перезагрузить
mods.reloadexit = Игра будет закрыта для перезагрузки модов. mods.reloadexit = Игра будет закрыта для перезагрузки модификаций.
mod.display = [gray]Модификация:[orange] {0} mod.display = [gray]Модификация:[orange] {0}
mod.enabled = [lightgray]Включён mod.enabled = [lightgray]Включён
mod.disabled = [scarlet]Выключен mod.disabled = [scarlet]Выключен
@@ -290,6 +294,7 @@ cancelbuilding = [accent][[{0}][] для очистки плана
selectschematic = [accent][[{0}][] выделить и скопировать selectschematic = [accent][[{0}][] выделить и скопировать
pausebuilding = [accent][[{0}][] для приостановки строительства pausebuilding = [accent][[{0}][] для приостановки строительства
resumebuilding = [scarlet][[{0}][] для продолжения строительства resumebuilding = [scarlet][[{0}][] для продолжения строительства
showui = Интерфейс скрыт.\nНажмите [accent][[{0}][] для отображения интерфейса.
wave = [accent]Волна {0} wave = [accent]Волна {0}
wave.cap = [accent]Волна {0}/{1} wave.cap = [accent]Волна {0}/{1}
wave.waiting = [lightgray]Волна через {0} wave.waiting = [lightgray]Волна через {0}
@@ -297,6 +302,8 @@ wave.waveInProgress = [lightgray]Волна продолжается
waiting = [lightgray]Ожидание… waiting = [lightgray]Ожидание…
waiting.players = Ожидание игроков… waiting.players = Ожидание игроков…
wave.enemies = [lightgray]Враги: {0} wave.enemies = [lightgray]Враги: {0}
wave.enemycores = [lightgray]Вражеских ядер: [accent]{0}
wave.enemycore = [accent]{0}[lightgray] вражеское ядро
wave.enemy = [lightgray]Остался {0} враг wave.enemy = [lightgray]Остался {0} враг
wave.guardianwarn = Волн до прибытия Стража: [accent]{0}[]. wave.guardianwarn = Волн до прибытия Стража: [accent]{0}[].
wave.guardianwarn.one = [accent]{0}[] волна до прибытия Стража. wave.guardianwarn.one = [accent]{0}[] волна до прибытия Стража.
@@ -486,8 +493,8 @@ complete = [lightgray]Необходимо:
requirement.wave = Достигните {0} волны в зоне {1} requirement.wave = Достигните {0} волны в зоне {1}
requirement.core = Уничтожьте вражеское ядро в зоне {0} requirement.core = Уничтожьте вражеское ядро в зоне {0}
requirement.research = Исследуйте {0} requirement.research = Исследуйте {0}
requirement.produce = Произведите {0}
requirement.capture = Захватите {0} requirement.capture = Захватите {0}
bestwave = [lightgray]Лучшая волна: {0}
launch.text = Высадка launch.text = Высадка
research.multiplayer = Только хост может исследовать предметы. research.multiplayer = Только хост может исследовать предметы.
uncover = Раскрыть uncover = Раскрыть
@@ -498,6 +505,7 @@ loadout = Груз
resources = Ресурсы resources = Ресурсы
bannedblocks = Запрещённые блоки bannedblocks = Запрещённые блоки
addall = Добавить всё addall = Добавить всё
launch.from = Запуск из: [accent]{0}
launch.destination = Место назначения: {0} launch.destination = Место назначения: {0}
configure.invalid = Количество должно быть числом между 0 и {0}. configure.invalid = Количество должно быть числом между 0 и {0}.
zone.unlocked = Зона «[lightgray]{0}» теперь разблокирована. zone.unlocked = Зона «[lightgray]{0}» теперь разблокирована.
@@ -529,19 +537,36 @@ weather.fog.name = Туман
sectors.unexplored = [lightgray]Не исследовано sectors.unexplored = [lightgray]Не исследовано
sectors.resources = Ресурсы: sectors.resources = Ресурсы:
sectors.production = Производит: sectors.production = Производит:
sectors.export = Экспорт:
sectors.time = Время:
sectors.threat = Угроза:
sectors.wave = Волна:
sectors.stored = Накоплено: sectors.stored = Накоплено:
sectors.resume = Продолжить sectors.resume = Продолжить
sectors.launch = Высадка sectors.launch = Высадка
sectors.select = Выбор sectors.select = Выбор
sectors.nonelaunch = [lightgray]нет (солнце) sectors.nonelaunch = [lightgray]нет (солнце)
sectors.rename = Переименовать сектор sectors.rename = Переименовать сектор
sector.curcapture = Сектор захвачен
sector.missingresources = [scarlet]Недостаточно ресурсов для высадки sector.missingresources = [scarlet]Недостаточно ресурсов для высадки
sector.attacked = Сектор [accent]{0}[white] атакован!
sector.lost = Сектор [accent]{0}[white] потерян!
#note: the missing space in the line below is intentional (недостающий пробел управляется кодом)
sector.captured = Сектор [accent]{0}[white]захвачен!
threat.low = Низкая
threat.medium = Средняя
threat.high = Высокая
threat.extreme = Экстремальная
threat.eradication = Истребляющая
planets = Планеты
planet.serpulo.name = Серпуло planet.serpulo.name = Серпуло
#TODO better name
planet.sun.name = Солнце planet.sun.name = Солнце
#NOTE TO TRANSLATORS: don't bother editing these, they'll be removed and/or rewritten anyway sector.impact0078.name = Крушение 0078
sector.groundZero.name = Отправная точка sector.groundZero.name = Отправная точка
sector.craters.name = Кратеры sector.craters.name = Кратеры
sector.frozenForest.name = Ледяной лес sector.frozenForest.name = Ледяной лес
@@ -553,10 +578,10 @@ sector.overgrowth.name = Заросли
sector.tarFields.name = Дегтярные поля sector.tarFields.name = Дегтярные поля
sector.saltFlats.name = Соляные равнины sector.saltFlats.name = Соляные равнины
sector.fungalPass.name = Грибной перевал sector.fungalPass.name = Грибной перевал
sector.biomassFacility.name = Центр исследования биомассы
#unused sector.windsweptIslands.name = Штормовой архипелаг
#sector.impact0078.name = Воздействие 0078 sector.extractionOutpost.name = Добывающая база
#sector.crags.name = Скалы sector.planetaryTerminal.name = Планетарный пусковой терминал
sector.groundZero.description = Оптимальная локация для повторных игр. Низкая вражеская угроза. Немного ресурсов.\nСоберите как можно больше свинца и меди.\nДвигайтесь дальше. sector.groundZero.description = Оптимальная локация для повторных игр. Низкая вражеская угроза. Немного ресурсов.\nСоберите как можно больше свинца и меди.\nДвигайтесь дальше.
sector.frozenForest.description = Даже здесь, ближе к горам, споры распространились. Холодные температуры не могут сдерживать их вечно.\n\nНачните вкладываться в энергию. Постройте генераторы внутреннего сгорания. Научитесь пользоваться регенератором. sector.frozenForest.description = Даже здесь, ближе к горам, споры распространились. Холодные температуры не могут сдерживать их вечно.\n\nНачните вкладываться в энергию. Постройте генераторы внутреннего сгорания. Научитесь пользоваться регенератором.
@@ -568,7 +593,7 @@ sector.overgrowth.description = Эта заросшая область нахо
sector.tarFields.description = Окраина зоны нефтедобычи, между горами и пустыней. Один из немногих районов с полезными запасами дёгтя.\nХотя эта область заброшенна, в ней поблизости присутствуют некоторые опасные вражеские силы. Не стоит их недооценивать.\n\n[lightgray]Исследуйте технологию переработки нефти, если возможно. sector.tarFields.description = Окраина зоны нефтедобычи, между горами и пустыней. Один из немногих районов с полезными запасами дёгтя.\nХотя эта область заброшенна, в ней поблизости присутствуют некоторые опасные вражеские силы. Не стоит их недооценивать.\n\n[lightgray]Исследуйте технологию переработки нефти, если возможно.
sector.desolateRift.description = Чрезвычайно опасная зона. Обилие ресурсов, но мало места. Высокий риск разрушения. Эвакуироваться нужно как можно скорее. Не расслабляйтесь во время больших перерывов между вражескими атаками. sector.desolateRift.description = Чрезвычайно опасная зона. Обилие ресурсов, но мало места. Высокий риск разрушения. Эвакуироваться нужно как можно скорее. Не расслабляйтесь во время больших перерывов между вражескими атаками.
sector.nuclearComplex.description = Бывший завод по производству и переработке тория, превращенный в руины.\n[lightgray]Исследуйте торий и варианты его многочисленного применения.\n\nВраг присутствует здесь в большом числе, постоянно разведывая нападающих. sector.nuclearComplex.description = Бывший завод по производству и переработке тория, превращенный в руины.\n[lightgray]Исследуйте торий и варианты его многочисленного применения.\n\nВраг присутствует здесь в большом числе, постоянно разведывая нападающих.
sector.fungalPass.description = Переходная область между высокими горами и более низкими, покрытыми спорами землями. Здесь расположена небольшая разведывательная база противника.\nУничтожьте ее.\nИспользуйте единицы «Кинжал» и «Камикадзе». Достаньте до обоих ядер. sector.fungalPass.description = Переходная область между высокими горами и более низкими, покрытыми спорами землями. Здесь расположена небольшая разведывательная база противника.\nУничтожьте ее.\nИспользуйте единицы «Кинжал» и «Ползун». Достаньте до обоих ядер.
settings.language = Язык settings.language = Язык
settings.data = Игровые данные settings.data = Игровые данные
@@ -628,6 +653,8 @@ stat.memorycapacity = Размер памяти
stat.basepowergeneration = Базовая генерация энергии stat.basepowergeneration = Базовая генерация энергии
stat.productiontime = Время производства stat.productiontime = Время производства
stat.repairtime = Время полной регенерации stat.repairtime = Время полной регенерации
stat.weapons = Орудия
stat.bullet = Снаряд
stat.speedincrease = Увеличение скорости stat.speedincrease = Увеличение скорости
stat.range = Радиус действия stat.range = Радиус действия
stat.drilltier = Бурит stat.drilltier = Бурит
@@ -697,12 +724,14 @@ units.processorcontrol = [lightgray]Управляется процессоро
bullet.damage = [stat]{0}[lightgray] урона bullet.damage = [stat]{0}[lightgray] урона
bullet.splashdamage = [stat]{0}[lightgray] урона в радиусе ~[stat] {1}[lightgray] блоков bullet.splashdamage = [stat]{0}[lightgray] урона в радиусе ~[stat] {1}[lightgray] блоков
bullet.incendiary = [stat]зажигательный bullet.incendiary = [stat]зажигательный
bullet.sapping = [stat]истощающий
bullet.homing = [stat]самонаводящийся bullet.homing = [stat]самонаводящийся
bullet.shock = [stat]шоковый bullet.shock = [stat]шоковый
bullet.frag = [stat]осколочный bullet.frag = [stat]осколочный
bullet.knockback = [stat]{0}[lightgray] отдачи bullet.knockback = [stat]{0}[lightgray] отдачи
bullet.pierce = [stat]{0}[lightgray]x пробитие bullet.pierce = [stat]{0}[lightgray]x пробитие
bullet.infinitepierce = [stat]бесконечное пробитие bullet.infinitepierce = [stat]бесконечное пробитие
bullet.healpercent = [stat]{0}[lightgray]% лечение
bullet.freezing = [stat]замораживающий bullet.freezing = [stat]замораживающий
bullet.tarred = [stat]замедляющий, горючий bullet.tarred = [stat]замедляющий, горючий
bullet.multiplier = [stat]{0}[lightgray]x множитель боеприпасов bullet.multiplier = [stat]{0}[lightgray]x множитель боеприпасов
@@ -922,6 +951,7 @@ content.item.name = Предметы
content.liquid.name = Жидкости content.liquid.name = Жидкости
content.unit.name = Боевые единицы content.unit.name = Боевые единицы
content.block.name = Блоки content.block.name = Блоки
content.sector.name = Секторы
item.copper.name = Медь item.copper.name = Медь
item.lead.name = Свинец item.lead.name = Свинец
@@ -1079,7 +1109,6 @@ block.conveyor.name = Конвейер
block.titanium-conveyor.name = Титановый конвейер block.titanium-conveyor.name = Титановый конвейер
block.plastanium-conveyor.name = Пластановый конвейер block.plastanium-conveyor.name = Пластановый конвейер
block.armored-conveyor.name = Бронированный конвейер block.armored-conveyor.name = Бронированный конвейер
block.armored-conveyor.description = Перемещает предметы вперёд. Не принимает вход по бокам.
block.junction.name = Перекрёсток block.junction.name = Перекрёсток
block.router.name = Маршрутизатор block.router.name = Маршрутизатор
block.distributor.name = Распределитель block.distributor.name = Распределитель
@@ -1087,7 +1116,6 @@ block.sorter.name = Сортировщик
block.inverted-sorter.name = Инвертированный сортировщик block.inverted-sorter.name = Инвертированный сортировщик
block.message.name = Сообщение block.message.name = Сообщение
block.illuminator.name = Осветитель block.illuminator.name = Осветитель
block.illuminator.description = Излучает свет.
block.overflow-gate.name = Избыточный затвор block.overflow-gate.name = Избыточный затвор
block.underflow-gate.name = Избыточный шлюз block.underflow-gate.name = Избыточный шлюз
block.silicon-smelter.name = Кремниевая плавильня block.silicon-smelter.name = Кремниевая плавильня
@@ -1187,6 +1215,7 @@ block.overdrive-dome.name = Сверхприводный купол
block.block-forge.name = Завод блоков block.block-forge.name = Завод блоков
block.block-loader.name = Загрузчик блоков block.block-loader.name = Загрузчик блоков
block.block-unloader.name = Разгрузчик блоков block.block-unloader.name = Разгрузчик блоков
block.interplanetary-accelerator.name = Межпланетный ускоритель
block.switch.name = Переключатель block.switch.name = Переключатель
block.micro-processor.name = Микропроцессор block.micro-processor.name = Микропроцессор
@@ -1238,7 +1267,7 @@ item.coal.description = Используется как топливо и в п
item.coal.details = Похоже, что это окаменевшее растительное вещество, образовавшееся задолго до Посева. item.coal.details = Похоже, что это окаменевшее растительное вещество, образовавшееся задолго до Посева.
item.titanium.description = Широко используется в транспортировке жидкостей, бурах и авиации. item.titanium.description = Широко используется в транспортировке жидкостей, бурах и авиации.
item.thorium.description = Используется в прочных постройках и как ядерного топлива. item.thorium.description = Используется в прочных постройках и как ядерного топлива.
item.scrap.description = Может быть расплавлен и переработан в другие материалы. item.scrap.description = Используется в плавильнях и измельчителях для получения других материалов.
item.scrap.details = Остататки старых построек и единиц. item.scrap.details = Остататки старых построек и единиц.
item.silicon.description = Используется в солнечных панелях, сложной электронике и самонаводящихся боеприпасах для турелей. item.silicon.description = Используется в солнечных панелях, сложной электронике и самонаводящихся боеприпасах для турелей.
item.plastanium.description = Используется в продвинутой авиации, изоляции и осколочных боеприпасах. item.plastanium.description = Используется в продвинутой авиации, изоляции и осколочных боеприпасах.
@@ -1248,11 +1277,15 @@ item.spore-pod.description = Используется для переработ
item.spore-pod.details = Споры. Похоже на синтетическую форму жизни. Выделяет газы, токсичные для других биологических форм жизни. Чрезвычайно инвазивны. Легко воспламеняется при определенных условиях. item.spore-pod.details = Споры. Похоже на синтетическую форму жизни. Выделяет газы, токсичные для других биологических форм жизни. Чрезвычайно инвазивны. Легко воспламеняется при определенных условиях.
item.blast-compound.description = Используется в бомбах и взрывчатых веществах. item.blast-compound.description = Используется в бомбах и взрывчатых веществах.
item.pyratite.description = Используется в зажигательном оружии и твердотопливных генераторах. item.pyratite.description = Используется в зажигательном оружии и твердотопливных генераторах.
liquid.water.description = Используется для охлаждения машин и переработки отходов. liquid.water.description = Используется для охлаждения машин и переработки отходов.
liquid.slag.description = Может быть переработан в разделителе на составляющие металлы или распылён на врагов в качестве оружия. liquid.slag.description = Может быть переработан в разделителе на составляющие металлы или распылён на врагов в качестве оружия.
liquid.oil.description = Используется в производстве продвинутых материалов и как зажигательный боеприпас. liquid.oil.description = Используется в производстве продвинутых материалов и как зажигательный боеприпас.
liquid.cryofluid.description = Используется в качестве охлаждающей жидкости для реакторов, турелей и фабрик. liquid.cryofluid.description = Используется в качестве охлаждающей жидкости для реакторов, турелей и фабрик.
block.resupply-point.description = Снаряжает медными боеприпасами ближайщие боевые единицы. Не совместим с единицами, требующими питания от батареи.
block.armored-conveyor.description = Перемещает предметы вперёд. Не принимает вход по бокам.
block.illuminator.description = Излучает свет.
block.message.description = Сохраняет сообщение для связи между союзниками. block.message.description = Сохраняет сообщение для связи между союзниками.
block.graphite-press.description = Сжимает куски угля в листы графита. block.graphite-press.description = Сжимает куски угля в листы графита.
block.multi-press.description = Сжимает куски угля в листы графита. Требуется вода в качестве охлаждающей жидкости. block.multi-press.description = Сжимает куски угля в листы графита. Требуется вода в качестве охлаждающей жидкости.
@@ -1393,6 +1426,7 @@ block.memory-cell.description = Хранит информацию для лог
block.memory-bank.description = Хранит информацию для логического процессора. Большая ёмкость. block.memory-bank.description = Хранит информацию для логического процессора. Большая ёмкость.
block.logic-display.description = Отображает произвольную графику из логического процессора. block.logic-display.description = Отображает произвольную графику из логического процессора.
block.large-logic-display.description = Отображает произвольную графику из логического процессора. block.large-logic-display.description = Отображает произвольную графику из логического процессора.
block.interplanetary-accelerator.description = Массивный рельсотронный ускоритель. Разгоняет ядро до второй космической скорости для межпланетных размещений.
unit.dagger.description = Стреляет стандартными пулями по всем врагам поблизости. unit.dagger.description = Стреляет стандартными пулями по всем врагам поблизости.
unit.mace.description = Стреляет потоками огня по всем врагам поблизости. unit.mace.description = Стреляет потоками огня по всем врагам поблизости.

View File

@@ -17,10 +17,12 @@ linkfail = Не вдалося перейти за посиланням!\nURL-а
screenshot = Зняток мапи збережено до {0} screenshot = Зняток мапи збережено до {0}
screenshot.invalid = Мапа занадто велика, тому, мабуть, не вистачає пам’яті для знятку мапи. screenshot.invalid = Мапа занадто велика, тому, мабуть, не вистачає пам’яті для знятку мапи.
gameover = Гра завершена gameover = Гра завершена
gameover.disconnect = Від’єднатися
gameover.pvp = [accent]{0}[] команда перемогла! gameover.pvp = [accent]{0}[] команда перемогла!
gameover.waiting = [accent]Очікуємо наступно мапу…
highscore = [accent]Новий рекорд! highscore = [accent]Новий рекорд!
copied = Скопійовано. copied = Скопійовано.
indev.popup = Наразі [accent]6.0[] знаходиться у стадії [accent]бета-тестування[].\n[lightgray]Це означає наступне:[]\n- Не вистачає наповнення кампанії;\n- Звуки і музика відсутні або незавершені;\n- Кампанія повністю не є завершеною;\n- Усе, що ви бачите, може змінитися або видалитися.\n\nПовідомляйте про вади або збої на [accent]Github[], а про помилки в перекладі в Discord. indev.popup = Наразі [accent]6.0[] знаходиться у стадії [accent]бета-тестування[].\n[lightgray]Це означає наступне:[]\n- Не вистачає наповнення кампанії;\n- Кампанія повністю не є завершеною;\n- Усе, що ви бачите, може змінитися або видалитися.\n\nПовідомляйте про вади або збої на [accent]Github[], а про помилки в перекладі в Discord.
indev.notready = Ця частина гри ще не готова. indev.notready = Ця частина гри ще не готова.
load.sound = Звуки load.sound = Звуки
@@ -57,6 +59,7 @@ schematic.rename = Перейменувати схему
schematic.info = {0}x{1}, блоків: {2} schematic.info = {0}x{1}, блоків: {2}
schematic.disabled = [scarlet]Схеми вимкнені[]\nВам не дозволяється використовувати схеми на цій [accent]мапі[] чи [accent]сервері. schematic.disabled = [scarlet]Схеми вимкнені[]\nВам не дозволяється використовувати схеми на цій [accent]мапі[] чи [accent]сервері.
stats = Статистика
stat.wave = Хвиль відбито:[accent] {0} stat.wave = Хвиль відбито:[accent] {0}
stat.enemiesDestroyed = Противників знищено:[accent] {0} stat.enemiesDestroyed = Противників знищено:[accent] {0}
stat.built = Будівель збудовано:[accent] {0} stat.built = Будівель збудовано:[accent] {0}
@@ -171,7 +174,7 @@ server.kicked.customClient = Цей сервер не підтримує кор
server.kicked.gameover = Гру завершено! server.kicked.gameover = Гру завершено!
server.kicked.serverRestarting = Сервер перезавантажується server.kicked.serverRestarting = Сервер перезавантажується
server.versions = Ваша версія:[accent] {0}[]\nВерсія на сервері:[accent] {1}[] server.versions = Ваша версія:[accent] {0}[]\nВерсія на сервері:[accent] {1}[]
host.info = Кнопка [accent]Сервер[] розміщує сервер на порті [scarlet]6567[]. \nКористувачі, які перебувають в тій же [lightgray]WiFi або локальній мережах[], мають побачити ваш сервер у своєму списку серверів.\n\nЯкщо ви хочете, щоби люди могли приєднуватися з будь-якої точки планети через IP, то потрібно зробити[accent] переадресація порту[].\n\n[lightgray]Примітка. Якщо у вас виникли проблеми з приєднанням до вашої локальної гри, переконайтеся, що ви надали Mindustry доступ до вашої локальної мережі в налаштуваннях брандмауера. Зауважте, що публічні мережі іноді не дають змогу виявити сервер. host.info = Кнопка [accent]Сервер[] розміщує сервер на порті [scarlet]6567[].\nКористувачі, які перебувають в тій же [lightgray]WiFi або локальній мережах[], мають побачити ваш сервер у своєму списку серверів.\n\nЯкщо ви хочете, щоби люди могли приєднуватися з будь-якої точки планети через IP, то потрібно зробити[accent] переадресація порту[].\n\n[lightgray]Примітка. Якщо у вас виникли проблеми з приєднанням до вашої локальної гри, переконайтеся, що ви надали Mindustry доступ до вашої локальної мережі в налаштуваннях брандмауера. Зауважте, що публічні мережі іноді не дають змогу виявити сервер.
join.info = Тут ви можете ввести [accent]IP сервера[] для під’єднання або знайти сервери у [accent]локальній[] чи [accent]глобальній мережі[] для приєднання до них.\nПідтримується локальна мережа(LAN) і широкосмугова мережа(WAN).\n\n[lightgray] Примітка. Це не є автоматичним глобальним списком серверів; якщо ви хочете приєднатися до когось через IP, вам доведеться попросити власника сервера дати свій ip. join.info = Тут ви можете ввести [accent]IP сервера[] для під’єднання або знайти сервери у [accent]локальній[] чи [accent]глобальній мережі[] для приєднання до них.\nПідтримується локальна мережа(LAN) і широкосмугова мережа(WAN).\n\n[lightgray] Примітка. Це не є автоматичним глобальним списком серверів; якщо ви хочете приєднатися до когось через IP, вам доведеться попросити власника сервера дати свій ip.
hostserver = Запустити багатокористувацький сервер hostserver = Запустити багатокористувацький сервер
invitefriends = Запросити друзів invitefriends = Запросити друзів
@@ -189,6 +192,10 @@ servers.local = Локальні сервери
servers.remote = Віддалені сервери servers.remote = Віддалені сервери
servers.global = Глобальні сервери servers.global = Глобальні сервери
servers.showhidden = Показати приховані сервери
server.shown = Показано
server.hidden = Приховано
trace = Стежити за гравцем trace = Стежити за гравцем
trace.playername = Ім’я гравця: [accent]{0} trace.playername = Ім’я гравця: [accent]{0}
trace.ip = IP: [accent]{0} trace.ip = IP: [accent]{0}
@@ -267,6 +274,9 @@ cancel = Скасувати
openlink = Перейти за посиланням openlink = Перейти за посиланням
copylink = Скопіювати посилання copylink = Скопіювати посилання
back = Назад back = Назад
crash.export = Експортувати аварійні звіти
crash.none = Аварійних звітів не знайдено
crash.exported = Аварійні звіти експортовано
data.export = Вивантажити дані data.export = Вивантажити дані
data.import = Завантажити дані data.import = Завантажити дані
data.openfolder = Відчинити теку з даними data.openfolder = Відчинити теку з даними
@@ -283,6 +293,7 @@ cancelbuilding = [accent][[{0}][], щоб очистити план
selectschematic = [accent][[{0}][], щоби вибрати та скопіювати selectschematic = [accent][[{0}][], щоби вибрати та скопіювати
pausebuilding = [accent][[{0}][], щоби призупинити будування pausebuilding = [accent][[{0}][], щоби призупинити будування
resumebuilding = [scarlet][[{0}][], щоби продовжити будування resumebuilding = [scarlet][[{0}][], щоби продовжити будування
showui = Користувацький інтерфейс приховано.\nНатисніть [accent][[{0}][], щоби показати його знову.
wave = [accent]Хвиля {0} wave = [accent]Хвиля {0}
wave.cap = [accent]Хвиля {0}/{1} wave.cap = [accent]Хвиля {0}/{1}
wave.waiting = [lightgray]Наступна хвиля\nчерез {0} wave.waiting = [lightgray]Наступна хвиля\nчерез {0}
@@ -290,6 +301,8 @@ wave.waveInProgress = [lightgray]Хвиля триває
waiting = [lightgray]Очікування… waiting = [lightgray]Очікування…
waiting.players = Очікування гравців… waiting.players = Очікування гравців…
wave.enemies = Залишилося\n[lightgray]{0} противник. wave.enemies = Залишилося\n[lightgray]{0} противник.
wave.enemycores = Ворожих ядер: [accent]{0}[lightgray]
wave.enemycore = [accent]{0}[lightgray] вороже ядро
wave.enemy = Залишився\n[lightgray]{0} противник wave.enemy = Залишився\n[lightgray]{0} противник
wave.guardianwarn = Хвиль до появи Вартового: [accent]{0}[] . wave.guardianwarn = Хвиль до появи Вартового: [accent]{0}[] .
wave.guardianwarn.one = Вартовий з’явиться через [accent]{0}[] хвилю. wave.guardianwarn.one = Вартовий з’явиться через [accent]{0}[] хвилю.
@@ -350,6 +363,7 @@ waves.invalid = Недійсні хвилі в буфері обміну.
waves.copied = Хвилі скопійовані. waves.copied = Хвилі скопійовані.
waves.none = Противники не були встановлені.\nЗазначимо, що пусті хвилі будуть автоматично замінені звичайною хвилею. waves.none = Противники не були встановлені.\nЗазначимо, що пусті хвилі будуть автоматично замінені звичайною хвилею.
#these are intentionally in lower case
wavemode.counts = кількість wavemode.counts = кількість
wavemode.totals = усього wavemode.totals = усього
wavemode.health = здоров’я wavemode.health = здоров’я
@@ -462,6 +476,8 @@ load = Завантажити
save = Зберегти save = Зберегти
fps = FPS: {0} fps = FPS: {0}
ping = Затримка: {0} мс ping = Затримка: {0} мс
memory = Mem: {0}мб
memory2 = Mem:\n {0}мб +\n {1}мб
language.restart = Перезапустіть свою гру, щоби налаштування мови набули чинності. language.restart = Перезапустіть свою гру, щоби налаштування мови набули чинності.
settings = Налаштування settings = Налаштування
tutorial = Навчання tutorial = Навчання
@@ -475,8 +491,9 @@ locked = Заблоковано
complete = [lightgray]Необхідно: complete = [lightgray]Необхідно:
requirement.wave = Досягніть хвилі {0} у зоні «{1}» requirement.wave = Досягніть хвилі {0} у зоні «{1}»
requirement.core = Знищте вороже ядро в зоні «{0}» requirement.core = Знищте вороже ядро в зоні «{0}»
requirement.research = Research {0} requirement.research = Дослідіть {0}
requirement.capture = Capture {0} requirement.produce = Виробіть {0}
requirement.capture = Захопіть {0}
bestwave = [lightgray]Найкраща хвиля: {0} bestwave = [lightgray]Найкраща хвиля: {0}
launch.text = Запуск launch.text = Запуск
research.multiplayer = Лише власник сервера має змогу досліджувати предмети. research.multiplayer = Лише власник сервера має змогу досліджувати предмети.
@@ -497,7 +514,7 @@ zone.objective = [lightgray]Мета: [accent]{0}
zone.objective.survival = вижити zone.objective.survival = вижити
zone.objective.attack = знищити вороже ядро zone.objective.attack = знищити вороже ядро
add = Додати… add = Додати…
boss.health = Здоров’я босу boss.health = Здоров’я Вартового
connectfail = [crimson]Помилка з’єднання:\n\n[accent]{0} connectfail = [crimson]Помилка з’єднання:\n\n[accent]{0}
error.unreachable = Сервер не є доступним.\nЧи правильно написана адреса? error.unreachable = Сервер не є доступним.\nЧи правильно написана адреса?
@@ -519,17 +536,37 @@ weather.fog.name = Туман
sectors.unexplored = [lightgray]Не досліджено sectors.unexplored = [lightgray]Не досліджено
sectors.resources = Ресурси: sectors.resources = Ресурси:
sectors.production = Виробництво: sectors.production = Виробництво:
sectors.export = Експортування:
sectors.time = Час:
sectors.threat = Загроза:
sectors.wave = Хвиля:
sectors.stored = Зберігає: sectors.stored = Зберігає:
sectors.resume = Продовжити sectors.resume = Продовжити
sectors.launch = Запустити sectors.launch = Запустити
sectors.select = Вибрати sectors.select = Вибрати
sectors.nonelaunch = [lightgray]нічого (сонце) sectors.nonelaunch = [lightgray]нічого (сонце)
sectors.rename = Перейменування сектора sectors.rename = Перейменування сектора
sector.curcapture = Сектор захоплено
sector.missingresources = [scarlet]Недостатньо ресурсів в ядрі sector.missingresources = [scarlet]Недостатньо ресурсів в ядрі
sector.attacked = Сектор [accent]{0}[white] під атакою!
sector.lost = Сектор [accent]{0}[white] втрачено!
#note: the missing space in the line below is intentional
sector.captured = Сектор [accent]{0}[white]захоплено!
threat.low = низька
threat.medium = середня
threat.high = висока
threat.extreme = екстремальна
threat.eradication = викорінювальна
planets = Планети
planet.serpulo.name = Cерпуло planet.serpulo.name = Cерпуло
#TODO better name
planet.sun.name = Сонце planet.sun.name = Сонце
#NOTE TO TRANSLATORS: don't bother editing these, they'll be removed and/or rewritten anyway
sector.impact0078.name = Аварійне приземлення 0078
sector.groundZero.name = Відправний пункт sector.groundZero.name = Відправний пункт
sector.craters.name = Кратери sector.craters.name = Кратери
sector.frozenForest.name = Крижаний ліс sector.frozenForest.name = Крижаний ліс
@@ -541,6 +578,12 @@ sector.overgrowth.name = Зарості
sector.tarFields.name = Дьогтьові поля sector.tarFields.name = Дьогтьові поля
sector.saltFlats.name = Соляні рівнини sector.saltFlats.name = Соляні рівнини
sector.fungalPass.name = Грибний перевал sector.fungalPass.name = Грибний перевал
sector.biomassFacility.name = Центр дослідження синтезу біомаси
sector.windsweptIslands.name = Вітряні острови
sector.extractionOutpost.name = Видобувна застава
#unused
#sector.crags.name = Crags
sector.groundZero.description = Оптимальне місце для повторних ігор. Низька ворожа загроза. Мало ресурсів.\nЗбирайте якомога більше свинцю та міді.\nНе затримуйтесь і йдіть далі. sector.groundZero.description = Оптимальне місце для повторних ігор. Низька ворожа загроза. Мало ресурсів.\nЗбирайте якомога більше свинцю та міді.\nНе затримуйтесь і йдіть далі.
sector.frozenForest.description = Спори поширилися навіть тут, ближче до гір. Холодна температура не може стримувати їх завжди.\n\nЗважтесь створити енергію. Побудуйте генератори внутрішнього згорання. Навчіться користуватися регенераторами. sector.frozenForest.description = Спори поширилися навіть тут, ближче до гір. Холодна температура не може стримувати їх завжди.\n\nЗважтесь створити енергію. Побудуйте генератори внутрішнього згорання. Навчіться користуватися регенераторами.
@@ -582,8 +625,9 @@ error.title = [crimson]Виникла помилка
error.crashtitle = Виникла помилка error.crashtitle = Виникла помилка
unit.nobuild = [scarlet]Ця одиниця не може будувати unit.nobuild = [scarlet]Ця одиниця не може будувати
lastaccessed = [lightgray]Остання зміна від {0} lastaccessed = [lightgray]Остання зміна від {0}
block.unknown = [lightgray]ШО ЗА??? block.unknown = [lightgray]???
stat.description = Призначення
stat.input = Ввід stat.input = Ввід
stat.output = Вивід stat.output = Вивід
stat.booster = Прискорювач stat.booster = Прискорювач
@@ -611,6 +655,8 @@ stat.memorycapacity = Ємність пам’яті
stat.basepowergeneration = Базова генерація енергії stat.basepowergeneration = Базова генерація енергії
stat.productiontime = Час виробництва stat.productiontime = Час виробництва
stat.repairtime = Час повного відновлення блоку stat.repairtime = Час повного відновлення блоку
stat.weapons = Зброя
stat.bullet = Кулі
stat.speedincrease = Збільшення швидкості stat.speedincrease = Збільшення швидкості
stat.range = Радіус дії stat.range = Радіус дії
stat.drilltier = Видобуває stat.drilltier = Видобуває
@@ -623,7 +669,7 @@ stat.maxconsecutive = Максимальна послідовність
stat.buildcost = Вартість будування stat.buildcost = Вартість будування
stat.inaccuracy = Розкид stat.inaccuracy = Розкид
stat.shots = Постріли stat.shots = Постріли
stat.reload = Постріли/секунду stat.reload = Постріли за сек.
stat.ammo = Боєприпаси stat.ammo = Боєприпаси
stat.shieldhealth = Міцність щита stat.shieldhealth = Міцність щита
stat.cooldowntime = Тривалість охолодження stat.cooldowntime = Тривалість охолодження
@@ -634,7 +680,7 @@ stat.lightningdamage = Шкода від удару блискавки
stat.flammability = Займистість stat.flammability = Займистість
stat.radioactivity = Радіоактивність stat.radioactivity = Радіоактивність
stat.heatcapacity = Теплоємність stat.heatcapacity = Теплоємність
stat.viscosity = В'язкість stat.viscosity = Вязкість
stat.temperature = Температура stat.temperature = Температура
stat.speed = Швидкість stat.speed = Швидкість
stat.buildspeed = Швидкість будування stat.buildspeed = Швидкість будування
@@ -651,6 +697,7 @@ ability.repairfield = Ремонтувальне поле
ability.statusfield = Поле підсилення ability.statusfield = Поле підсилення
ability.unitspawn = Завод одиниць «{0}» ability.unitspawn = Завод одиниць «{0}»
ability.shieldregenfield = Поле, що відновлює щити ability.shieldregenfield = Поле, що відновлює щити
ability.movelightning = Блискавки при русі
bar.drilltierreq = Потребується кращий бур bar.drilltierreq = Потребується кращий бур
bar.noresources = Бракує ресурсів bar.noresources = Бракує ресурсів
@@ -679,12 +726,14 @@ units.processorcontrol = [lightgray]Керується процесором
bullet.damage = [stat]{0}[lightgray] шкода bullet.damage = [stat]{0}[lightgray] шкода
bullet.splashdamage = [stat]{0}[lightgray] шкода по ділянці ~[stat] {1}[lightgray] плиток bullet.splashdamage = [stat]{0}[lightgray] шкода по ділянці ~[stat] {1}[lightgray] плиток
bullet.incendiary = [stat]запальний bullet.incendiary = [stat]запальний
bullet.sapping = [stat]виснажує
bullet.homing = [stat]самонаведення bullet.homing = [stat]самонаведення
bullet.shock = [stat]шок bullet.shock = [stat]шок
bullet.frag = [stat]шкода по ділянці bullet.frag = [stat]шкода по ділянці
bullet.knockback = [stat]{0}[lightgray] відкидання bullet.knockback = [stat]{0}[lightgray] відкидання
bullet.pierce = [stat]{0}[lightgray]x пробиття bullet.pierce = [stat]{0}[lightgray]x пробиття
bullet.infinitepierce = [stat]пробиття bullet.infinitepierce = [stat]пробиття
bullet.healpercent = [stat]{0}[lightgray]% лікування
bullet.freezing = [stat]заморожування bullet.freezing = [stat]заморожування
bullet.tarred = [stat]дьогтьовий bullet.tarred = [stat]дьогтьовий
bullet.multiplier = [stat]{0}[lightgray]x патронів bullet.multiplier = [stat]{0}[lightgray]x патронів
@@ -709,6 +758,7 @@ unit.items = предм.
unit.thousands = тис unit.thousands = тис
unit.millions = млн unit.millions = млн
unit.billions = млрд unit.billions = млрд
category.purpose = Призначення
category.general = Загальне category.general = Загальне
category.power = Енергія category.power = Енергія
category.liquids = Рідини category.liquids = Рідини
@@ -722,6 +772,7 @@ setting.blockreplace.name = Пропонування щодо автоматич
setting.linear.name = Лінійна фільтрація setting.linear.name = Лінійна фільтрація
setting.hints.name = Підказки setting.hints.name = Підказки
setting.flow.name = Показувати темп швидкості ресурсів setting.flow.name = Показувати темп швидкості ресурсів
setting.backgroundpause.name = Пауза при згортанн
setting.buildautopause.name = Автоматичне призупинення будування setting.buildautopause.name = Автоматичне призупинення будування
setting.animatedwater.name = Анімаційні рідини setting.animatedwater.name = Анімаційні рідини
setting.animatedshields.name = Анімаційні щити setting.animatedshields.name = Анімаційні щити
@@ -916,7 +967,7 @@ item.surge-alloy.name = Кінетичний сплав
item.spore-pod.name = Споровий стручок item.spore-pod.name = Споровий стручок
item.sand.name = Пісок item.sand.name = Пісок
item.blast-compound.name = Вибухова суміш item.blast-compound.name = Вибухова суміш
item.pyratite.name = Піротит item.pyratite.name = Пиротит
item.metaglass.name = Метаскло item.metaglass.name = Метаскло
item.scrap.name = Брухт item.scrap.name = Брухт
liquid.water.name = Вода liquid.water.name = Вода
@@ -935,7 +986,7 @@ unit.atrax.name = Атракс
unit.spiroct.name = Павучник unit.spiroct.name = Павучник
unit.arkyid.name = Аркиїд unit.arkyid.name = Аркиїд
unit.toxopid.name = Отруйник unit.toxopid.name = Отруйник
unit.flare.name = Фальшфеєр unit.flare.name = Фальшфейєр
unit.horizon.name = Горизонт unit.horizon.name = Горизонт
unit.zenith.name = Зеніт unit.zenith.name = Зеніт
unit.antumbra.name = Тіньовик unit.antumbra.name = Тіньовик
@@ -946,10 +997,10 @@ unit.mega.name = Мега
unit.quad.name = Квад unit.quad.name = Квад
unit.oct.name = Окт unit.oct.name = Окт
unit.risso.name = Грампус unit.risso.name = Грампус
unit.minke.name = Смугач малий unit.minke.name = Смугач
unit.bryde.name = Смугач Брайда unit.bryde.name = Брайд
unit.sei.name = Смугач Сейвал unit.sei.name = Сейвал
unit.omura.name = Смугач Омури unit.omura.name = Омура
unit.alpha.name = Альфа unit.alpha.name = Альфа
unit.beta.name = Бета unit.beta.name = Бета
unit.gamma.name = Гамма unit.gamma.name = Гамма
@@ -989,7 +1040,7 @@ block.thruster.name = Штовхач
block.kiln.name = Піч block.kiln.name = Піч
block.graphite-press.name = Графітний прес block.graphite-press.name = Графітний прес
block.multi-press.name = Мультипрес block.multi-press.name = Мультипрес
block.constructing = {0}\n[lightgray](В процесі) block.constructing = {0}\n[lightgray](У процесі)
block.spawn.name = Місце появи противника block.spawn.name = Місце появи противника
block.core-shard.name = Ядро «Уламок» block.core-shard.name = Ядро «Уламок»
block.core-foundation.name = Ядро «Штаб» block.core-foundation.name = Ядро «Штаб»
@@ -1059,7 +1110,6 @@ block.conveyor.name = Конвеєр
block.titanium-conveyor.name = Титановий конвеєр block.titanium-conveyor.name = Титановий конвеєр
block.plastanium-conveyor.name = Пластанієвий конвеєр block.plastanium-conveyor.name = Пластанієвий конвеєр
block.armored-conveyor.name = Броньований конвеєр block.armored-conveyor.name = Броньований конвеєр
block.armored-conveyor.description = Переміщує предмети з тією ж швидкістю, що й титанові конвеєри, але має більше міцності. Не приймає введення з боків ні з чого, крім інших конвеєрних стрічок.
block.junction.name = Перехрестя block.junction.name = Перехрестя
block.router.name = Маршрутизатор block.router.name = Маршрутизатор
block.distributor.name = Розподілювач block.distributor.name = Розподілювач
@@ -1067,7 +1117,6 @@ block.sorter.name = Сортувальник
block.inverted-sorter.name = Зворотній сортувальник block.inverted-sorter.name = Зворотній сортувальник
block.message.name = Повідомлення block.message.name = Повідомлення
block.illuminator.name = Освітлювач block.illuminator.name = Освітлювач
block.illuminator.description = Невелике, компактне, джерело світла, яку можна налаштувати. Для роботи потребує енергії.
block.overflow-gate.name = Надмірний затвор block.overflow-gate.name = Надмірний затвор
block.underflow-gate.name = Недостатній затвор block.underflow-gate.name = Недостатній затвор
block.silicon-smelter.name = Кремнієвий плавильний завод block.silicon-smelter.name = Кремнієвий плавильний завод
@@ -1112,7 +1161,7 @@ block.ripple.name = Ряб
block.phase-conveyor.name = Фазовий конвеєр block.phase-conveyor.name = Фазовий конвеєр
block.bridge-conveyor.name = Мостовий конвеєр block.bridge-conveyor.name = Мостовий конвеєр
block.plastanium-compressor.name = Пластанієвий компресор block.plastanium-compressor.name = Пластанієвий компресор
block.pyratite-mixer.name = Змішувач піротита block.pyratite-mixer.name = Змішувач пиротита
block.blast-mixer.name = Змішувач вибухонебезпечного з’єднання block.blast-mixer.name = Змішувач вибухонебезпечного з’єднання
block.solar-panel.name = Сонячна панель block.solar-panel.name = Сонячна панель
block.solar-panel-large.name = Велика сонячна панель block.solar-panel-large.name = Велика сонячна панель
@@ -1162,7 +1211,11 @@ block.payload-conveyor.name = Вантажний конвеєр
block.payload-router.name = Розвантажувальний маршрутизатор block.payload-router.name = Розвантажувальний маршрутизатор
block.disassembler.name = Розбирач block.disassembler.name = Розбирач
block.silicon-crucible.name = Кремнієвий тигель block.silicon-crucible.name = Кремнієвий тигель
block.overdrive-dome.name = Величний Прискорювач block.overdrive-dome.name = Великий прискорювач
#experimental, may be removed
block.block-forge.name = Блок-кузня
block.block-loader.name = Блок-завантажувач
block.block-unloader.name = Блок-вивантажувач
block.switch.name = Перемикач block.switch.name = Перемикач
block.micro-processor.name = Мікропроцесор block.micro-processor.name = Мікропроцесор
@@ -1203,136 +1256,205 @@ tutorial.waves = [lightgray]Противник[] з’явився.\n\nЗахи
tutorial.waves.mobile = [lightgray]Противник[] з’явився.\n\nЗахистіть ядро від двох хвиль. Ваш корабель буде автоматично атакувати противників.\nПобудуйте більше башт і бурів. Добудьте більше міді. tutorial.waves.mobile = [lightgray]Противник[] з’явився.\n\nЗахистіть ядро від двох хвиль. Ваш корабель буде автоматично атакувати противників.\nПобудуйте більше башт і бурів. Добудьте більше міді.
tutorial.launch = Як тільки ви досягнете певної хвилі, ви зможете[accent] запустити ядро[], залишивши свою базу позаду, та [accent]отримати всі ресурси у вашому ядрі.[]\nЦі отримані ресурси можуть бути використані для дослідження нових технологій.\n\n[accent]Натисніть кнопку запуску. tutorial.launch = Як тільки ви досягнете певної хвилі, ви зможете[accent] запустити ядро[], залишивши свою базу позаду, та [accent]отримати всі ресурси у вашому ядрі.[]\nЦі отримані ресурси можуть бути використані для дослідження нових технологій.\n\n[accent]Натисніть кнопку запуску.
item.copper.description = Початковий будівельний матеріал. Широко використовується у всіх типах блоків. item.copper.description = Використовується у всіх типах блоків і боєприпасах.
item.lead.description = Основний початковий матеріал. Широко застосовується в електроніці та в транспортуванні рідин. item.copper.details = Мідь. Напрочуд багато жил цієї руди на Серпуло. За своєю структурою слабка, якщо не зміцнена.
item.metaglass.description = Дуже жорсткий склад скла. Широко застосовується для розподілу та зберігання рідини. item.lead.description = Широко використовується в електроніці та в транспортуванні рідин.
item.graphite.description = Мінералізований вуглець, що використовується для боєприпасів та як електричний компонент. item.lead.details = Сплав. Інертний. Широко використовується в акумуляторах.\nПримітка. Мабуть, токсичний для біологічних форм життя. Не те щоб тут залишилося багато...
item.sand.description = Поширений матеріал, який широко використовується у виплавці, як під час сплавлення, так і в якості відходів. item.metaglass.description = Використовується для розподілу чи зберігання рідини.
item.coal.description = Скам’янілі рослинні речовини, що утворилися задовго до посіву. Широко використовується для виробництва пального та ресурсів. item.graphite.description = Використовується для боєприпасів та електричних компонентів.
item.titanium.description = Рідкісний надлегкий метал, який широко використовується для транспортування рідини, бурів і літаків. item.sand.description = Використовується для виробництва інших удосконалених матеріалів.
item.thorium.description = Щільний радіоактивний метал, що використовується в якості конструкційної опори та ядерного палива. item.coal.description = Використовується для виробництва палива і вдосноналених матеріалів.
item.scrap.description = Залишки старих споруд та підрозділів. Містить мікроелементи багатьох різних металів. item.coal.details = Виглядає скам’янілою рослинною речовиною, утвореною задовго до Сівби.
item.silicon.description = Надзвичайно корисний напівпровідник. Має застосування в сонячних батареях, складній електроніці та боєприпасах для башт. item.titanium.description = Використовується в транспортуванні рідин, бурів та авіації.
item.plastanium.description = Легкий пластичний матеріал, що використовується в сучасних літальних апаратах та у фрагментованих боєприпасах. item.thorium.description = Використовується в міцних конструкціях і як ядерне паливо.
item.phase-fabric.description = Майже невагома речовина, що застосовується в передовій електроніці та в технології самовідновлення. item.scrap.description = Використовується у Плавильнях і Подрібнювачах для переробки в інші матеріали в інші матеріали.
item.surge-alloy.description = Удосконалений сплав з унікальними електричними властивостями. item.scrap.details = Залишки старих споруд та підрозділів.
item.spore-pod.description = Струмок синтетичних спор, синтезований з атмосферних концентрацій для промислових цілей. Використовується для перетворення на нафту, вибухівку та паливо. item.silicon.description = Використовується в сонячних панелях, складній електроніці та боєприпасах самонаведення для башт.
item.blast-compound.description = Нестабільна сполука, яка використовується в бомбах і вибухівках. Синтезується зі спорових стручків та інших летких речовин. Використовувати як паливо не рекомендується. item.plastanium.description = Використовується в передових одиницях та у фрагментованих боєприпасах.
item.pyratite.description = Надзвичайно легкозаймиста речовина, що використовується в запальній зброї. item.phase-fabric.description = Використовується в передовій електроніці і технології самовідновлення.
liquid.water.description = Найкорисніша рідина. Зазвичай використовується для охолодження машин та перероблювання відходів. item.surge-alloy.description = Використовується в передовій зброї та реактивних захисних конструкціях.
liquid.slag.description = Різні види розплавленого металу змішуються між собою. Може бути відокремлений від складових корисних копалин або розпорошений на ворожі частини як зброя. item.spore-pod.description = Використовується для перетворення на нафту, вибухівку та паливо.
liquid.oil.description = Рідина, яка використовується у виробництві сучасних матеріалів. Може бути перетворена у вугілля в якості палива або використана як куля. item.spore-pod.details = Спори. Найімовірніше, синтетична форма життя. Виділяють гази, токсичні для іншого біологічного життя. Надзвичайно загарбницька поведінка. Легкозаймисті при певних умовах.
liquid.cryofluid.description = Інертна рідина, що створена з води та титану. Має здатність надзвичайно високою пропускною спроможністю. Широко використовується в якості рідини, що охолоджує. item.blast-compound.description = Використовується в бомбах та в розривних боєприпасах.
item.pyratite.description = Використовується в запальній зброї і твердопаливних генераторах.
liquid.water.description = Використовується для охолодження машин та перероблювання відходів.
liquid.slag.description = Переробляється у відокремлювачах у складові метали або розпорошується на ворогів як зброя.
liquid.oil.description = Використовується у виробництві передових матеріалів і як запальні боєприпаси.
liquid.cryofluid.description = Використовується як теплоносій в реакторах, баштах і заводах.
block.message.description = Зберігає повідомлення. Використовується для комунікації між союзниками. block.armored-conveyor.description = Переміщує предмети вперед. Не приймає введення з боків ні з чого, крім інших конвеєрних стрічок.
block.graphite-press.description = Стискає шматки вугілля в чисті аркуші графіту. block.illuminator.description = Випромінює світло.
block.multi-press.description = Модернізована версія графітового преса. Використовує воду та енергію для швидкого та ефективного перероблювання вугілля. block.message.description = Зберігає повідомлення для комунікації між союзниками.
block.silicon-smelter.description = Змішує пісок із чистим вугіллям. Виробляє кремній. block.graphite-press.description = Стискає вугілля в графіт.
block.kiln.description = Виплавляє пісок та свинець у сполуку, відому як метаскло. Для запуску потрібна невелика кількість енергії. block.multi-press.description = Стискає вугілля в графіт. Потребує воду для охолодження.
block.plastanium-compressor.description = Виробляє пластаній із нафти та титану. block.silicon-smelter.description = Синтезує пісок з вугіллям для отримання кремнію.
block.phase-weaver.description = Синтезує фазову тканину з радіоактивного торію та піску. Для роботи потрібна велика кількість енергії. block.kiln.description = Виплавляє пісок та свинець у метаскло.
block.plastanium-compressor.description = Виробляє пластаній із нафти і титану.
block.phase-weaver.description = Синтезує фазову тканину з торію та піску.
block.alloy-smelter.description = Поєднує титан, свинець, кремній і мідь для отримання кінетичного сплаву. block.alloy-smelter.description = Поєднує титан, свинець, кремній і мідь для отримання кінетичного сплаву.
block.cryofluid-mixer.description = Змішує воду і дрібний порошок титану в кріогенну рідину. Основне використання в торієвому реактору. block.cryofluid-mixer.description = Змішує воду і подрібнений титан, щоб виробити кріогенну рідину.
block.blast-mixer.description = Подрібнює і змішує скупчення спор із піротитом для отримання вибухової суміші. block.blast-mixer.description = Виробляє вибухову суміш з піратиту і спорових стручків.
block.pyratite-mixer.description = Змішує вугілля, свинець та пісок у легкозаймистий піротит. block.pyratite-mixer.description = Змішує вугілля, свинець та пісок у легкозаймистий пиротит.
block.melter.description = Розплавляє брухт у шлак для подальшого перероблювання, або використання в баштах «Хвиля». block.melter.description = Розплавляє брухт у шлак.
block.separator.description = Відокремлює шлак на його мінеральні компоненти. Виводить охолоджені матеріали. block.separator.description = Відокремлює шлак на його мінеральні компоненти.
block.spore-press.description = Стискає спорові стручки під сильним тиском для синтезу нафти. block.spore-press.description = Стискає спорові стручки для синтезування нафти.
block.pulverizer.description = Подрібнює брухт у дрібний пісок. block.pulverizer.description = Подрібнює брухт у дрібний пісок.
block.coal-centrifuge.description = Нафта перетворюється в шматки вугілля. block.coal-centrifuge.description = Нафта перетворюється у вугілля.
block.incinerator.description = Випаровує будь-який зайвий предмет або рідину, які він отримує. block.incinerator.description = Випаровує будь-який предмет або рідину, що отримує.
block.power-void.description = Знищує будь-яку енергію, до якої він під’єднаний. Тільки пісочниця. block.power-void.description = Знищує будь-яку під’єднану енергію. Тільки пісочниця.
block.power-source.description = Постійно створює енергію. Тільки пісочниця. block.power-source.description = Постійно генерує енергію. Тільки пісочниця.
block.item-source.description = Постійно створює предмети. Тільки пісочниця. block.item-source.description = Постійно створює предмети. Тільки пісочниця.
block.item-void.description = Знищує будь-які предмети. Тільки пісочниця. block.item-void.description = Руйнує будь-які предмети. Тільки пісочниця.
block.liquid-source.description = Постійно створює рідини. Тільки пісочниця. block.liquid-source.description = Постійно виробляє рідини. Тільки пісочниця.
block.liquid-void.description = Видаляє будь-які рідини. Тільки пісочниця. block.liquid-void.description = Випаровує будь-які рідини. Тільки пісочниця.
block.copper-wall.description = Дешевий оборонний блок.\nКорисний для оборони ядра та башт у перші кілька хвиль. block.copper-wall.description = Захищає споруди від ворожих снарядів.
block.copper-wall-large.description = Дешевий оборонний блок.\nКорисний для оборони ядра та башт у перші кілька хвиль.\nЗаймає декілька плиток. block.copper-wall-large.description = Захищає споруди від ворожих снарядів.
block.titanium-wall.description = Порівняно сильний оборонний блок.\nЗабезпечує помірний оборони від противників. block.titanium-wall.description = Захищає споруди від ворожих снарядів.
block.titanium-wall-large.description = Порівняно сильний оборонний блок.\nЗабезпечує помірний оборони від противників.\nЗаймає декілька плиток. block.titanium-wall-large.description = Захищає споруди від ворожих снарядів.
block.plastanium-wall.description = Особливий тип стіни, який поглинає електричні дуги і блокує автоматичні з’єднання енергетичних вузлів. block.plastanium-wall.description = Захищає споруди від ворожих снарядів. Поглинає електричні дуги і лазери. Блокує автоматичні з’єднання енергетичних вузлів.
block.plastanium-wall-large.description = Особливий тип стіни, який поглинає електричні дуги і блокує автоматичні з’єднання енергетичних вузлів.\nЗаймає декілька плиток. block.plastanium-wall-large.description = Захищає споруди від ворожих снарядів. Поглинає електричні дуги і лазери. Блокує автоматичні з’єднання енергетичних вузлів.
block.thorium-wall.description = Сильний оборонний блок.\nГарна оборона від противників. block.thorium-wall.description = Захищає споруди від ворожих снарядів.
block.thorium-wall-large.description = Сильний оборонний блок.\nГарна оборона від противників.\nЗаймає декілька плиток. block.thorium-wall-large.description = Захищає споруди від ворожих снарядів.
block.phase-wall.description = Стіна має покриття спеціальним складом, що відбиває світло і який базується на фазовій тканині. Здебільшого відбиває кулі у разі удару. block.phase-wall.description = Захищає споруди від ворожих снарядів, відбиває більшість куль при зіткненні.
block.phase-wall-large.description = Стіна має покриття спеціальним складом, що відбиває світло і який базується на фазовій тканині. Здебільшого відбиває кулі у разі удару.\nЗаймає декілька плиток. block.phase-wall-large.description = Захищає споруди від ворожих снарядів, відбиває більшість куль при зіткненні.
block.surge-wall.description = Надзвичайно міцний оборонний блок.\nЗбільшує заряд, якщо контактуватиме з кулями, вивільняючи його випадковим чином. block.surge-wall.description = Захищає споруди від ворожих снарядів, періодично випускає електричні дуги при зіткненні.
block.surge-wall-large.description = Надзвичайно міцний оборонний блок.\nЗбільшує заряд, якщо контактуватиме з кулями, вивільняючи його випадковим чином.\nЗаймає декілька плиток. block.surge-wall-large.description = Захищає споруди від ворожих снарядів, періодично випускає електричні дуги при зіткненні.
block.door.description = Невеликі двері. Можна відчинити або зачинити, натиснувши на них. block.door.description = Стіна, яку можна відкрити і закрити.
block.door-large.description = Великі двері. Можна відчинити та зачинити, натиснувши на них.\nЗаймає декілька плиток. block.door-large.description = Стіна, яку можна відкрити і закрити.
block.mender.description = Періодично ремонтує блоки в його радіусі дії. Боронить башти та стіни.\nЗа бажанням, можна використати кремній для підвищення дальності та ефективності. block.mender.description = Періодично ремонтує блоки в своєму радіусі дії.\nЗа бажанням можна використати кремній задля підвищення радіусу дії й ефективності.
block.mend-projector.description = Покращена версія «Регенератора». Періодично ремонтує блоки в його радіусі дії.\nЗа бажанням, можна використати фазову тканину для підвищення дальності та ефективності. block.mend-projector.description = Ремонтує блоки в своєму радіусі дії.\nЗа бажанням можна використати фазову тканину задля підвищення радіусу дії й ефективності.
block.overdrive-projector.description = Збільшує швидкість найближчих будівель.\nЗа бажанням, можна використати фазову тканину для підвищення дальності та ефективності. block.overdrive-projector.description = Збільшує швидкість найближчих будівель.\nЗа бажанням можна використати фазову тканину задля підвищення радіусу дії й ефективності.
block.force-projector.description = Створює навколо себе шестикутне силове поле, боронячи будівлі та блоки всередині від пошкоджень.\nПерегрівається, якщо завдано занадто великої шкоди. За бажанням, можна використати теплоносій для запобігання перегріву. Для збільшення розміру щита можна використовувати фазову тканину. block.force-projector.description = Створює навколо себе шестикутне силове поле, захищаючи будівлі та блоки всередині від пошкоджень.\nПерегрівається, якщо завдано занадто великої шкоди. За бажанням можна використати теплоносій для запобігання перегріву. Для збільшення розміру щита можна використовувати фазову тканину.
block.shock-mine.description = Наносить шкоду противникам, коли вони наступають на міну. Майже невидима для противника. block.shock-mine.description = Випускає електричні дуги при контакті з ворогом.
block.conveyor.description = Базовий транспортний блок. Переміщує елементи вперед і автоматично перетворює їх у блоки. Можна обертати. block.conveyor.description = Переміщує елементи вперед.
block.titanium-conveyor.description = Покращений блок транспорту елементів. Переміщує предмети швидше, ніж звичайні конвеєри. block.titanium-conveyor.description = Переміщує предмети швидше, ніж звичайний конвеєр.
block.plastanium-conveyor.description = Переміщує предмети партіями.\nПриймає елементи на задній частині та вивантажує їх у трьох напрямках спереду.\nПотребує кілька точок завантаження та розвантаження для максимальної пропускної здатності. block.plastanium-conveyor.description = Переміщує предмети партіями. Приймає елементи на задній частині та вивантажує їх у трьох напрямках спереду. Потребує кілька точок завантаження та розвантаження для максимальної пропускної здатності.
block.junction.description = Діє як міст для двох перехресних конвеєрних стрічок. Корисно в ситуаціях, коли два різних конвеєри перевозять різні матеріали в різні місця. block.junction.description = Діє як міст для двох перехресних конвеєрних стрічок.
block.bridge-conveyor.description = Покращений блок транспорту елементів. Дає змогу транспортувати предмети до 3-ох плиток із будь-якої місцевості чи будівлі. block.bridge-conveyor.description = Транспортує предмети через будівлі або місцевість
block.phase-conveyor.description = Покращений блок транспорту елементів. Використовує енергію для телепортування елементів на під’єднаний фазовий конвеєр через кілька плиток. block.phase-conveyor.description = Миттєво транспортує предмети через місцевості або будівлі. Більший діапазон, ніж у мостового конвеєра, але потребує енергії.
block.sorter.description = Сортує предмети. Якщо елемент відповідає вибраному, його можна передати. В іншому випадку елемент виводиться зліва та/чи справа. block.sorter.description = Якщо елемент відповідає вибраному, його можна передати. В іншому випадку елемент виводиться ліворуч та праворуч.
block.inverted-sorter.description = Обробляє елементи, як звичайний сортувальник, але виводить обрані елементи на сторони. block.inverted-sorter.description = Схожий на звичайний сортувальник, але виводить обрані елементи на бокові сторони.
block.router.description = Приймає елементи з одного напрямку та виводить їх до трьох інших напрямків порівну. Корисно для поділу матеріалів від одного джерела до кількох цілей.\n\n[scarlet]Ніколи не використовуйте поруч із входами до механізмів, оскільки вони будуть забиті вихідними предметами.[] block.router.description = Розподіляє елементи, що надходять, порівну на 3 різні напрямки.
block.distributor.description = Поліпшений маршрутизатор. Розділяє предмети до 7 інших напрямків порівну. block.router.details = Необхідне зло. Не використовуйте поруч із входами до механізмів, оскільки вони, входи, будуть забиті вихідними предметами.
block.overflow-gate.description = Вивантажує лише вліво та/або вправо, якщо передній шлях заблокований. block.distributor.description = Розділяє предмети до 7 інших напрямків порівну.
block.underflow-gate.description = Повна протилежність надмірному затвору. Виводить предмет прямо, якщо лівий та/або правий шлях заблоковано. block.overflow-gate.description = Вивантажує лише ліворуч і праворуч, якщо передній шлях заблокований.
block.underflow-gate.description = Повна протилежність надмірному затвору. Виводить предмет прямо, якщо лівий і правий шлях заблоковано.
block.mass-driver.description = Найкращий блок для транспортування предметів. Збирає кілька предметів, а потім вистрілює їх до іншої електромагнітної катапульти на велику відстань. Для роботи потребує енергія. block.mass-driver.description = Найкращий блок для транспортування предметів. Збирає кілька предметів, а потім вистрілює їх до іншої електромагнітної катапульти на велику відстань. Для роботи потребує енергія.
block.mechanical-pump.description = Дешевий насос із повільним виходом, але не потребує енергоспоживання. block.mechanical-pump.description = Дешевий насос із повільним виходом, але не потребує енергоспоживання.
block.rotary-pump.description = Удосконалений насос. Насоси більше викачують, але потребують енергію. block.rotary-pump.description = Удосконалений насос. Насоси більше викачують, але потребують енергію.
block.thermal-pump.description = Найкращий насос. block.thermal-pump.description = Найкращий насос.
block.conduit.description = Основний блок транспортування рідини. Пересуває рідини вперед. Застосовується спільно з насосами та іншими трубопроводами. block.conduit.description = Пересуває рідини вперед. Застосовується спільно з насосами та іншими трубопроводами.
block.pulse-conduit.description = Удосконалений блок транспортування рідини. Швидше транспортує й більше зберігає рідини, ніж стандартні трубопроводи. block.pulse-conduit.description = Пересуває рідини вперед. Швидше транспортує і зберігає більше рідини, ніж стандартні трубопроводи.
block.plated-conduit.description = Переміщує рідини з тією ж швидкістю, що й імпульсні трубопроводи, але має більше міцності. Не приймає рідин із боків окрім інших трубопроводів.\nНе протікає. block.plated-conduit.description = Пересуває рідини вперед. Не приймає рідин із боків окрім інших трубопроводів. Не протікає.
block.liquid-router.description = Приймає рідини з одного напрямку та виводить їх до трьох інших напрямків порівну. Також можна зберігати певну кількість рідини. Корисно для розщеплення рідин від одного джерела до кількох мішеней. block.liquid-router.description = Приймає рідини з одного напрямку та виводить їх до трьох інших напрямків порівну. Також може зберігати певну кількість рідини.
block.liquid-tank.description = Зберігає велику кількість рідини. Використовуйте для створення буферів у ситуаціях із непостійним попитом на матеріали або як гарантію охолодження життєво важливих блоків. block.liquid-tank.description = Зберігає велику кількість рідини. Виводить воду на всі сторони, через це схожий на рідинний маршрутизатор.
block.liquid-junction.description = Діє як міст для двох каналів, що перетинаються. Корисно в ситуаціях, коли два різні трубопроводи транспортують різні рідини в різні місця. block.liquid-junction.description = Діє як міст для двох трубопроводів.
block.bridge-conduit.description = Удосконалений блок транспортування рідини. Надає можливість транспортувати рідину до 3 плиток будь-якої місцевості чи будівлі. block.bridge-conduit.description = Транспортує рідину через місцевість і будівлі.
block.phase-conduit.description = Удосконалений блок транспортування рідини. Використовує енергію для транспортування рідин до приєднаного фазового каналу через декілька плиток. block.phase-conduit.description = Транспортує рідину через місцевість і будівлі. Діапазон дії більший ніж у мостового трубопровода
block.power-node.description = Передає живлення на приєднані вузли. Вузол буде отримувати живлення від будь-яких сусідніх блоків або подавати живлення до них. block.power-node.description = Передає живлення на приєднані вузли. Вузол буде отримувати живлення від будь-яких сусідніх блоків або подавати живлення до них.
block.power-node-large.description = Поліпшений вузол живлення з більшим радіусом дії. block.power-node-large.description = Передовий вузол живлення з більшим радіусом дії.
block.surge-tower.description = Вузол живлення з меншою кількістю доступних з’єднань і з найбільшим радіусом дії. block.surge-tower.description = Вузол живлення з меншою кількістю доступних з’єднань і з найбільшим радіусом дії.
block.diode.description = Живлення акумулятора може протікати через цей блок лише в одному напрямку, але лише в тому випадку, якщо інша сторона має менше енергії. block.diode.description = Живлення акумулятора може протікати через цей блок лише в одному напрямку, але лише в тому випадку, якщо інша сторона має менше енергії.
block.battery.description = Зберігає енергію як буфер у часи надлишкової енергії. Виводить енергію в періоди дефіциту. block.battery.description = Зберігає енергію як буфер у часи надлишкової енергії. Виводить енергію в періоди дефіциту.
block.battery-large.description = Зберігає набагато більше енергії, ніж звичайний акумулятор. block.battery-large.description = Зберігає енергію як буфер у часи надлишкової енергії. Виводить енергію в періоди дефіциту. Більша ємність ніж у звичайного акумулятора.
block.combustion-generator.description = Виробляє енергію, спалюючи легкозаймисті матеріали, такі як вугілля. block.combustion-generator.description = Виробляє енергію, спалюючи легкозаймисті матеріали, як-от вугілля.
block.thermal-generator.description = Генерує енергію у разі розміщення в спекотних місцях. block.thermal-generator.description = Виробляє енергію при розміщенні в спекотних місцях.
block.steam-generator.description = Удосконалений генератор згоряння. Більш ефективний, але потребує додаткової води для отримання пари. block.steam-generator.description = Виробляє енергію, спалюючи легкозаймисті матеріали і перетворює воду в пару.
block.differential-generator.description = Удосконалений генератор згоряння. Використовує різницю температур між кріогенною рідиною й піротитом, що горить. block.differential-generator.description = Виробляє велику кількість енергії. Використовує різницю температур між кріогенною рідиною й пиротитом, що горить.
block.rtg-generator.description = Простий і надійний генератор. Використовує тепло радіоактивних сполук, які розкладаються, для отримання енергії з повільною швидкістю. block.rtg-generator.description = Використовує тепло радіоактивних сполук, які розкладаються, для отримання енергії з повільною швидкістю.
block.solar-panel.description = Забезпечує невелику кількість енергії від сонця. block.solar-panel.description = Забезпечує невелику кількість енергії від сонця.
block.solar-panel-large.description = Значно ефективніша ніж стандартна сонячна панель. block.solar-panel-large.description = Забезпечує невелику кількість енергії від сонця. Значно ефективніша ніж стандартна сонячна панель.
block.thorium-reactor.description = Виробляє значну кількість енергії з торію. Вимагає постійного охолодження. Сильно вибухне, якщо подаватиметься недостатня кількість теплоносія. Вихідна потужність залежить від заповненості, базова потужність генерується на повній місткості. block.thorium-reactor.description = Виробляє значну кількість енергії з торію. Потребує постійного охолодження. Сильно вибухне, якщо подаватиметься недостатня кількість теплоносія.
block.impact-reactor.description = Удосконалений генератор, здатний створювати величезну кількість енергії за максимальною ефективності. Для запуску процесу потрібно значні обсяги енергії. block.impact-reactor.description = Здатний створювати величезну кількість енергії за максимальною ефективності. Для запуску процесу потрібно значні обсяги енергії.
block.mechanical-drill.description = Недорогий бур. Якщо розмістити на доречних плитках, то виводитиме предмети постійно, але повільно. Придатний лише для базових ресурсів. block.mechanical-drill.description = Якщо розмістити на доречних плитках, то виводитиме предмети постійно, але повільно. Придатний лише для базових ресурсів.
block.pneumatic-drill.description = Поліпшений бур, здатний видобувати титан. Видобуває швидше, ніж механічний бур. block.pneumatic-drill.description = Поліпшений бур, здатний видобувати титан. Видобуває швидше, ніж механічний бур.
block.laser-drill.description = Дає змогу виконувати буріння ще швидше за допомогою лазерної технології, але вимагає енергії. Придатний до видобутку торію. block.laser-drill.description = Дає змогу видобувати ще швидше за допомогою лазерної технології, але потребує енергії. здатний видобувати торій.
block.blast-drill.description = Найкращий бур. Потрібна велика кількість енергії. block.blast-drill.description = Найкращий бур. Потрібує великої кількості енергії.
block.water-extractor.description = Видобуває підземні води. Використовується в місцях, де немає поверхневої води. block.water-extractor.description = Викачує підземні води. Використовується в місцях, де немає поверхневої води.
block.cultivator.description = Культивує невеликі концентрації спор в атмосфері на готові до промисловості стручки. block.cultivator.description = Культивує невеликі концентрації спор в стручки.
block.oil-extractor.description = Для видобутку нафти використовується велика кількість енергії, піску та води. block.cultivator.details = Відновлена технологія. Використовується для отримання величезної кількості біомаси якомога ефективніше. Ймовірно, початковий інкубатор спор, що зараз покриває Серпуло.
block.core-shard.description = Найперша версія капсули ядра. Після його знищення всі контакти з регіоном втрачаються. Не допустіть цього. block.oil-extractor.description = Використовується велика кількість енергії, піску та води для отримання нафти.
block.core-foundation.description = Друга версія ядра. Краще броньована. Зберігає більше ресурсів. block.core-shard.description = Ядро бази. Після знищення сектор втрачається. Найперша версія капсули ядра. Після його знищення всі контакти з регіоном втрачаються. Не допустіть цього.
block.core-nucleus.description = Третя й остання версія капсули ядра. Надзвичайно добре броньована. Зберігає величезні обсяги ресурсів. block.core-shard.details = Найперша версія капсули ядра. Компактне. Самовідтворюванне. Оснащене одноразовими пусковими рушіями. Не призначено для міжпланетних подорожей.
block.core-foundation.description = Ядро бази. Добре броньоване. Зберігає більше ресурсів.
block.core-foundation.details = Друга версія ядра.
block.core-nucleus.description = Ядро бази. Напрочуд добре броньовано. Зберігає величезну кількість ресурсів.
block.core-nucleus.details = Третя і фінальна версія ядра.
block.vault.description = Зберігає велику кількість предметів кожного типу. Блок розвантажувача може використовуватися для отримання предметів зі сховища. block.vault.description = Зберігає велику кількість предметів кожного типу. Блок розвантажувача може використовуватися для отримання предметів зі сховища.
block.container.description = Зберігає малу кількість предметів кожного типу. Блок розвантажувача може використовуватися для отримання предметів зі сховища. block.container.description = Зберігає малу кількість предметів кожного типу. Блок розвантажувача може використовуватися для отримання предметів зі сховища.
block.unloader.description = Вивантажує предмети з блока, який не переміщує предмети, на конвеєр або безпосередньо в сусідній блок. Тип предмета для завантаження можна змінити, натиснувши на блок. block.unloader.description = Вивантажує предмети з найближчих блоків
block.launch-pad.description = Запускає партії предметів без необхідності запуску ядра. Стартовий майданчик надає можливість вам запускати ресурси кожні n секунд без необхідності завершувати гру. Просто подайте в нього ресурси та забезпечте енергією. block.launch-pad.description = Запускає партії предметів без необхідності запуску ядра.
block.launch-pad-large.description = Поліпшена версія стартового майданчика. Зберігає більше предметів. Запускається частіше. block.duo.description = Вистрілює по черзі кулями по ворогах.
block.duo.description = Мала й дешева башта. Корисна проти наземних одиниць. block.scatter.description = Вистрілює скупченням свинцю, брухту чи метаскла в повітряних противників.
block.scatter.description = Основна протиповітряна башта. Вистрілює грудочки свинцю, брухту чи метаскла в противників.
block.scorch.description = Підпалює будь-яких наземних противників поблизу. Високоефективна на близькій відстані. block.scorch.description = Підпалює будь-яких наземних противників поблизу. Високоефективна на близькій відстані.
block.hail.description = Невелика артилерійська башта з далеким радіусом дії. block.hail.description = Вистрілює невеликі снаряди в наземних ворогів на великі відстані.
block.wave.description = Башта середнього розміру. Випускає потоками рідини в противників. Автоматично гасить пожежі при постачанні води. block.wave.description = Вистрілює потоки рідин в ворогів. Автоматично гасить пожежі при постачанні води.
block.lancer.description = Лазерна башта середнього розміру, яка атакує наземних противників. Заряджає і вистрілює потужні пучки енергії. block.lancer.description = Заряджає і вистрілює потужні пучки енергії в наземних противників.
block.arc.description = Невелика електрична башта з малим радіусом дії. Стріляє дугами електрики в противників. block.arc.description = Вистрілює дугами електрики в наземних противників.
block.swarmer.description = Ракетна башта середнього розміру. Атакує як повітряних, так і наземних противників. Запускає ракети, які летять у противників самостійно. block.swarmer.description = Запускає ракети, що автоматично наводяться у противників.
block.salvo.description = Більш велика, вдосконалена версія башти «Подвійна». Вистрілює швидкий залп куль у противника. block.salvo.description = Вистрілює швидкий залп куль у противника.
block.fuse.description = Велика енергетична башта з малим радіусом дії. Стріляє трьома пронизливими променями на найближчих противників. block.fuse.description = Вистрілює трьома променями, що пронизують броню, у малому радіусі у противників.
block.ripple.description = Надзвичайно потужна артилерійська башта. На великі відстані стріляє скупченнями снарядів у противників. block.ripple.description = Вистрілює скупченням снарядів у противників.
block.cyclone.description = Велика протиповітряна та протиназемна башта. Підпалює вибухонебезпечними грудками скупчення противників. block.cyclone.description = Підпалює вибухові грудки скупчення противників.
block.spectre.description = Масивна двоствольна гармата. Стріляє великими бронебійними кулями в повітряні та наземні цілі. block.spectre.description = Вистрілює великі бронебійні кулі у повітряні та наземні цілі.
block.meltdown.description = Масивна лазерна гармата. Заряджає і стріляє лазерним променем у найближчих противників. Для роботи потрібен теплоносій. block.meltdown.description = Заряджає і вистріляє лазерним променем у найближчих противників. Для роботи потрібен теплоносій.
block.repair-point.description = Безперервно ремонтує найближчу пошкоджену бойову одиницю. block.foreshadow.description = Вистрілює великим болтом в одну ціль на велику дистанцію
block.repair-point.description = Безперервно ремонтує найближчу пошкоджену бойову одиницю у своєму радіусі дії.
block.segment.description = Пошкоджує та руйнує вхідні снаряди. Окрім лазерних. block.segment.description = Пошкоджує та руйнує вхідні снаряди. Окрім лазерних.
block.parallax.description = Притягає ворожі повітряні одиниці, пошкоджуючи їх в процесі.
block.tsunami.description = Вистрілює потужними потоками рідини у ворогів. Автоматично гасить пожежі при постачанні води.
block.silicon-crucible.description = Очищує кремній від піску та вугілля, використовуючи пиратит як додаткове джерело тепла. Більш ефективний у жарких місцях.
block.disassembler.description = Поділяє шлак на незначні кількості екзотичних мінеральних компонентів при низькій ефективності. Може виробляти торій.
block.overdrive-dome.description = Збільшує швидкість найближчих будівль. Потребує фазову тканину і кремній.
block.payload-conveyor.description = Переміщує великі вантажі, як-от одиниці з заводів.
block.payload-router.description = Розділяє вантажі, що надходять, у 3 різні сторони.
block.command-center.description = Контролює поведінку одиниць за допомогою декількох різних команд.
block.ground-factory.description = Виробляє наземних одиниць. Вивід одиниць можна здійснити безпосередньо на місцевість, або спрямувати до реконструкторів для поліпшення.
block.air-factory.description = Виробляє повітряних одиниць. Вивід одиниць можна здійснити безпосередньо на місцевість, або спрямувати до реконструкторів для поліпшення.
block.naval-factory.description = Виробляє одиниць. Вивід одиниць можна здійснити безпосередньо на місцевість, або спрямувати до реконструкторів для поліпшення.
block.additive-reconstructor.description = Поліпшує введених одиниць до другого рівня.
block.multiplicative-reconstructor.description = Поліпшує введених одиниць до третього рівня.
block.exponential-reconstructor.description = Поліпшує введених одиниць до четвертого рівня.
block.tetrative-reconstructor.description = Поліпшує введених одиниць до п’ятого і фінального рівня.
block.switch.description = Перемикач. Стан можна читати і контролювати за допомогою логічних процесорів.
block.micro-processor.description = Запускає послідовність логічних вказівок (інструкцій) у нескінченному циклі. Може використовуватися для керування блоків та будівель.
block.logic-processor.description = Запускає послідовність логічних вказівок (інструкцій) у нескінченному циклі. Може використовуватися для керування блоків та будівель. Швидше ніж Мікропроцесор.
block.hyper-processor.description = Запускає послідовність логічних вказівок (інструкцій) у нескінченному циклі. Може використовуватися для керування блоків та будівель. Швидше ніж Логічний процесор
block.memory-cell.description = Зберігає інформацію для логічного процесора.
block.memory-bank.description = Зберігає інформацію для логічного процесора. Висока місткість.
block.logic-display.description = Відображає довільну графіку з логічного процесора.
block.large-logic-display.description = Відображає довільну графіку з логічного процесора.
unit.dagger.description = Вистрілює стандартними кулями по найближчих ворогах.
unit.mace.description = Вистрілює потоками полум'я у найближчих ворогів.
unit.fortress.description = Вистрілює з дальнобійної артилерії по наземних цілях.
unit.scepter.description = Вистрілює шквалом заряджених куль у найближчих ворогів.
unit.reign.description = Вистрілює шквалом масивних пронизливих куль по найближчих ворогах.
unit.nova.description = Вистрілює лазерними болтами, які пошкоджують ворогів та відновлюють союзні споруди. Здатний до польоту.
unit.pulsar.description = Випускає дуги електрики, які завдають шкоди ворогам та відновлюють союзні споруди. Здатний до польоту.
unit.quasar.description = Вистрілює пробивними лазерними промені, які пошкоджують ворогів та відновлюють споріднені конструкції. Здатний до польоту. Захищений.
unit.vela.description = Вистрілює масивним безперервним лазерним промінем, який завдає шкоди ворогам, спричиняє пожежі та відновлює союзні споруди. Здатний до польоту.
unit.corvus.description = Спричиняє масивний лазерний вибух, який завдає шкоди ворогам та відновлює споріднені споруди. Може переступати через більшість місцевості.
unit.crawler.description = Біжить до ворогів і самознищується, викликаючи великий вибух.
unit.atrax.description = Випалює виснажливі шари шлаку в наземних цілях. Може переступити більшість місцевості.
unit.spiroct.description = Вистрілює виснажливими лазерними променями у ворогів, відновлюючись при цьому. Може переступати через більшість місцевості.
unit.arkyid.description = Вистрілює у ворогів великими виснажливими лазерними променями, відновлюючись при цьому.
unit.toxopid.description = Вистрілює у ворогів великими електричними касетними снарядами та пробивними лазерами. Може переступати через більшість місцевості.
unit.flare.description = Вистрілює стандартними кулями в найближчі цілі.
unit.horizon.description = Кидає купу бомб на наземні цілі.
unit.zenith.description = Вистрілює залпи ракет по всіх найближчих ворогів.
unit.antumbra.description = Вистрілює шквал куль у всіх найближчих ворогів.
unit.eclipse.description = Вистрілює два пронизливі лазери та шквал луски по всіх найближчих ворогах.
unit.mono.description = Автоматично видобуває мідь і свинець і кладе їх в ядро.
unit.poly.description = Автоматично перебудовує зруйновані споруди та допомагає іншим одиницям у будівництві.
unit.mega.description = Автоматично відновлює пошкоджені конструкції. Здатний нести блоки та невеликі наземні блоки.
unit.quad.description = Кидає великі бомби на наземні цілі, відновлюючи союзні споруди та завдаючи шкоди ворогам. Здатний нести середні наземні одиниці.
unit.oct.description = Захищає найближчих союзників своїм відновлювальним щитом. Здатний нести більшість наземних одиниць.
unit.risso.description = Вистрілює шквалом ракет і куль по всіх найближчих ворогах.
unit.minke.description = Вистрілює запальними снарядами та стандартнами кулями по найближчих наземних цілях.
unit.bryde.description = Вистрілює по ворогам артилерійськими снарядами та ракетами великої дальності.
unit.sei.description = Вистрілює по ворогам шквалом ракет і бронебійних куль.
unit.omura.description = Вистрілює по ворогах дальнобійним болтом, що пробиває броню. Виробляє повітряних Фальшфеєрів.
unit.alpha.description = Захищає ядро «Уламок» від противників. Будує споруди.
unit.beta.description = Захищає ядро «Штаб» від противників. Будує споруди.
unit.gamma.description = Захищає ядро «Атом» від противників. Будує споруди.

View File

@@ -96,6 +96,7 @@ YellOw139
PetrGasparik PetrGasparik
LeoDog896 LeoDog896
Summet Summet
MEEP of Faith
jalastram (freesound.org) jalastram (freesound.org)
newlocknew (freesound.org) newlocknew (freesound.org)
dsmolenaers (freesound.org) dsmolenaers (freesound.org)

View File

@@ -316,3 +316,4 @@
63420=space|block-space-medium 63420=space|block-space-medium
63419=legacy-unit-factory-air|block-legacy-unit-factory-air-medium 63419=legacy-unit-factory-air|block-legacy-unit-factory-air-medium
63418=legacy-unit-factory-ground|block-legacy-unit-factory-ground-medium 63418=legacy-unit-factory-ground|block-legacy-unit-factory-ground-medium
63417=interplanetary-accelerator|block-interplanetary-accelerator-medium

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 828 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 668 KiB

After

Width:  |  Height:  |  Size: 660 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 960 KiB

After

Width:  |  Height:  |  Size: 901 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 KiB

After

Width:  |  Height:  |  Size: 675 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

After

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 KiB

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -14,21 +14,20 @@ import static mindustry.Vars.*;
public class BuilderAI extends AIController{ public class BuilderAI extends AIController{
float buildRadius = 1500; float buildRadius = 1500;
boolean found = false; boolean found = false;
@Nullable Builderc following; @Nullable Unit following;
@Override @Override
public void updateMovement(){ public void updateMovement(){
Builderc builder = (Builderc)unit;
if(builder.moving()){ if(unit.moving()){
builder.lookAt(builder.vel().angle()); unit.lookAt(unit.vel.angle());
} }
if(target != null && shouldShoot()){ if(target != null && shouldShoot()){
unit.lookAt(target); unit.lookAt(target);
} }
builder.updateBuilding(true); unit.updateBuilding = true;
if(following != null){ if(following != null){
//try to follow and mimic someone //try to follow and mimic someone
@@ -36,18 +35,18 @@ public class BuilderAI extends AIController{
//validate follower //validate follower
if(!following.isValid() || !following.activelyBuilding()){ if(!following.isValid() || !following.activelyBuilding()){
following = null; following = null;
builder.plans().clear(); unit.plans.clear();
return; return;
} }
//set to follower's first build plan, whatever that is //set to follower's first build plan, whatever that is
builder.plans().clear(); unit.plans.clear();
builder.plans().addFirst(following.buildPlan()); unit.plans.addFirst(following.buildPlan());
} }
if(builder.buildPlan() != null){ if(unit.buildPlan() != null){
//approach request if building //approach request if building
BuildPlan req = builder.buildPlan(); BuildPlan req = unit.buildPlan();
boolean valid = boolean valid =
(req.tile().build instanceof ConstructBuild && req.tile().<ConstructBuild>bc().cblock == req.block) || (req.tile().build instanceof ConstructBuild && req.tile().<ConstructBuild>bc().cblock == req.block) ||
@@ -60,7 +59,7 @@ public class BuilderAI extends AIController{
moveTo(req.tile(), buildingRange - 20f); moveTo(req.tile(), buildingRange - 20f);
}else{ }else{
//discard invalid request //discard invalid request
builder.plans().removeFirst(); unit.plans.removeFirst();
} }
}else{ }else{
@@ -71,8 +70,8 @@ public class BuilderAI extends AIController{
Units.nearby(unit.team, unit.x, unit.y, buildRadius, u -> { Units.nearby(unit.team, unit.x, unit.y, buildRadius, u -> {
if(found) return; if(found) return;
if(u instanceof Builderc b && u != unit && b.activelyBuilding()){ if(u.canBuild() && u != unit && u.activelyBuilding()){
BuildPlan plan = b.buildPlan(); BuildPlan plan = u.buildPlan();
Building build = world.build(plan.x, plan.y); Building build = world.build(plan.x, plan.y);
if(build instanceof ConstructBuild cons){ if(build instanceof ConstructBuild cons){
@@ -80,7 +79,7 @@ public class BuilderAI extends AIController{
//make sure you can reach the request in time //make sure you can reach the request in time
if(dist / unit.speed() < cons.buildCost * 0.9f){ if(dist / unit.speed() < cons.buildCost * 0.9f){
following = b; following = u;
found = true; found = true;
} }
} }
@@ -98,7 +97,7 @@ public class BuilderAI extends AIController{
blocks.removeFirst(); blocks.removeFirst();
}else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid. }else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid.
//add build request. //add build request.
builder.addBuild(new BuildPlan(block.x, block.y, block.rotation, content.block(block.block), block.config)); unit.addBuild(new BuildPlan(block.x, block.y, block.rotation, content.block(block.block), block.config));
//shift build plan to tail so next unit builds something else. //shift build plan to tail so next unit builds something else.
blocks.addLast(blocks.removeFirst()); blocks.addLast(blocks.removeFirst());
}else{ }else{

View File

@@ -59,13 +59,13 @@ public class FormationAI extends AIController implements FormationMember{
unit.moveAt(realtarget.sub(unit).limit(speed)); unit.moveAt(realtarget.sub(unit).limit(speed));
} }
if(unit instanceof Minerc mine && leader instanceof Minerc com){ if(unit.canMine() && leader.canMine()){
if(com.mineTile() != null && mine.validMine(com.mineTile())){ if(leader.mineTile != null && unit.validMine(leader.mineTile)){
mine.mineTile(com.mineTile()); unit.mineTile(leader.mineTile);
CoreBuild core = unit.team.core(); CoreBuild core = unit.team.core();
if(core != null && com.mineTile().drop() != null && unit.within(core, unit.type.range) && !unit.acceptsItem(com.mineTile().drop())){ if(core != null && leader.mineTile.drop() != null && unit.within(core, unit.type.range) && !unit.acceptsItem(leader.mineTile.drop())){
if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){ if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){
Call.transferItemTo(unit.stack.item, unit.stack.amount, unit.x, unit.y, core); Call.transferItemTo(unit.stack.item, unit.stack.amount, unit.x, unit.y, core);
@@ -73,13 +73,13 @@ public class FormationAI extends AIController implements FormationMember{
} }
} }
}else{ }else{
mine.mineTile(null); unit.mineTile(null);
} }
} }
if(unit instanceof Builderc build && leader instanceof Builderc com && com.activelyBuilding()){ if(unit.canBuild() && leader.canBuild() && leader.activelyBuilding()){
build.clearBuilding(); unit.clearBuilding();
build.addBuild(com.buildPlan()); unit.addBuild(leader.buildPlan());
} }
} }

View File

@@ -92,9 +92,7 @@ public class LogicAI extends AIController{
} }
} }
case stop -> { case stop -> {
if(unit instanceof Builderc build){ unit.clearBuilding();
build.clearBuilding();
}
} }
} }

View File

@@ -17,21 +17,21 @@ public class MinerAI extends AIController{
protected void updateMovement(){ protected void updateMovement(){
Building core = unit.closestCore(); Building core = unit.closestCore();
if(!(unit instanceof Minerc miner) || core == null) return; if(!(unit.canMine()) || core == null) return;
if(miner.mineTile() != null && !miner.mineTile().within(unit, unit.type.range)){ if(unit.mineTile != null && !unit.mineTile.within(unit, unit.type.range)){
miner.mineTile(null); unit.mineTile(null);
} }
if(mining){ if(mining){
if(timer.get(timerTarget2, 60 * 4) || targetItem == null){ if(timer.get(timerTarget2, 60 * 4) || targetItem == null){
targetItem = unit.team.data().mineItems.min(i -> indexer.hasOre(i) && miner.canMine(i), i -> core.items.get(i)); targetItem = unit.team.data().mineItems.min(i -> indexer.hasOre(i) && unit.canMine(i), i -> core.items.get(i));
} }
//core full of the target item, do nothing //core full of the target item, do nothing
if(targetItem != null && core.acceptStack(targetItem, 1, unit) == 0){ if(targetItem != null && core.acceptStack(targetItem, 1, unit) == 0){
unit.clearItem(); unit.clearItem();
miner.mineTile(null); unit.mineTile(null);
return; return;
} }
@@ -47,7 +47,7 @@ public class MinerAI extends AIController{
moveTo(ore, unit.type.range / 2f, 20f); moveTo(ore, unit.type.range / 2f, 20f);
if(unit.within(ore, unit.type.range)){ if(unit.within(ore, unit.type.range)){
miner.mineTile(ore); unit.mineTile = ore;
} }
if(ore.block() != Blocks.air){ if(ore.block() != Blocks.air){
@@ -56,7 +56,7 @@ public class MinerAI extends AIController{
} }
} }
}else{ }else{
miner.mineTile(null); unit.mineTile = null;
if(unit.stack.amount == 0){ if(unit.stack.amount == 0){
mining = true; mining = true;

View File

@@ -27,13 +27,13 @@ public class SoundControl{
public Seq<Music> bossMusic = Seq.with(); public Seq<Music> bossMusic = Seq.with();
protected Music lastRandomPlayed; protected Music lastRandomPlayed;
protected Interval timer = new Interval(); protected Interval timer = new Interval(4);
protected @Nullable Music current; protected @Nullable Music current;
protected float fade; protected float fade;
protected boolean silenced; protected boolean silenced;
protected AudioBus uiBus = new AudioBus(); protected AudioBus uiBus = new AudioBus();
protected boolean wasPaused, wasPlaying; protected boolean wasPlaying;
protected AudioFilter filter = new BiquadFilter(){{ protected AudioFilter filter = new BiquadFilter(){{
set(0, 500, 1); set(0, 500, 1);
}}; }};
@@ -117,9 +117,8 @@ public class SoundControl{
fade = 0f; fade = 0f;
} }
//fade the lowpass filter in/out //fade the lowpass filter in/out, poll every 30 ticks just in case performance is an issue
if(paused != wasPaused){ if(timer.get(1, 30f)){
wasPaused = paused;
Core.audio.soundBus.fadeFilterParam(0, Filters.paramWet, paused ? 1f : 0f, 0.4f); Core.audio.soundBus.fadeFilterParam(0, Filters.paramWet, paused ? 1f : 0f, 0.4f);
} }

View File

@@ -89,7 +89,7 @@ public class Blocks implements ContentList{
message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank, message, switchBlock, microProcessor, logicProcessor, hyperProcessor, largeLogicDisplay, logicDisplay, memoryCell, memoryBank,
//campaign //campaign
launchPad, launchPadLarge, launchPad, launchPadLarge, interplanetaryAccelerator,
//misc experimental //misc experimental
blockForge, blockLoader, blockUnloader; blockForge, blockLoader, blockUnloader;
@@ -1777,7 +1777,7 @@ public class Blocks implements ContentList{
shootSound = Sounds.railgun; shootSound = Sounds.railgun;
unitSort = (u, x, y) -> -u.maxHealth; unitSort = (u, x, y) -> -u.maxHealth;
coolantMultiplier = 0.11f; coolantMultiplier = 0.2f;
health = 150 * size * size; health = 150 * size * size;
coolantUsage = 1f; coolantUsage = 1f;
@@ -2046,7 +2046,6 @@ public class Blocks implements ContentList{
//TODO remove //TODO remove
launchPadLarge = new LaunchPad("launch-pad-large"){{ launchPadLarge = new LaunchPad("launch-pad-large"){{
//requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.titanium, 200, Items.silicon, 150, Items.lead, 250, Items.plastanium, 75));
size = 4; size = 4;
itemCapacity = 300; itemCapacity = 300;
launchTime = 60f * 35; launchTime = 60f * 35;
@@ -2054,6 +2053,14 @@ public class Blocks implements ContentList{
consumes.power(6f); consumes.power(6f);
}}; }};
interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 9000, Items.silicon, 9000, Items.thorium, 9000, Items.titanium, 9000, Items.surgeAlloy, 5000, Items.phaseFabric, 4000));
researchCostMultiplier = 0.1f;
size = 7;
hasPower = true;
consumes.power(10f);
}};
//endregion campaign //endregion campaign
//region logic //region logic

View File

@@ -10,7 +10,7 @@ public class SectorPresets implements ContentList{
groundZero, groundZero,
craters, biomassFacility, frozenForest, ruinousShores, windsweptIslands, stainedMountains, tarFields, craters, biomassFacility, frozenForest, ruinousShores, windsweptIslands, stainedMountains, tarFields,
fungalPass, extractionOutpost, saltFlats, overgrowth, fungalPass, extractionOutpost, saltFlats, overgrowth,
impact0078, desolateRift, nuclearComplex; impact0078, desolateRift, nuclearComplex, planetaryTerminal;
@Override @Override
public void load(){ public void load(){
@@ -68,6 +68,7 @@ public class SectorPresets implements ContentList{
overgrowth = new SectorPreset("overgrowth", serpulo, 134){{ overgrowth = new SectorPreset("overgrowth", serpulo, 134){{
difficulty = 5; difficulty = 5;
useAI = false;
}}; }};
tarFields = new SectorPreset("tarFields", serpulo, 23){{ tarFields = new SectorPreset("tarFields", serpulo, 23){{
@@ -89,5 +90,9 @@ public class SectorPresets implements ContentList{
captureWave = 50; captureWave = 50;
difficulty = 7; difficulty = 7;
}}; }};
planetaryTerminal = new SectorPreset("planetaryTerminal", serpulo, 93){{
difficulty = 10;
}};
} }
} }

View File

@@ -30,6 +30,8 @@ public class TechTree implements ContentList{
node(junction, () -> { node(junction, () -> {
node(router, () -> { node(router, () -> {
node(launchPad, Seq.with(new SectorComplete(extractionOutpost)), () -> { node(launchPad, Seq.with(new SectorComplete(extractionOutpost)), () -> {
node(interplanetaryAccelerator, Seq.with(new SectorComplete(planetaryTerminal)), () -> {
});
}); });
node(distributor); node(distributor);
@@ -47,7 +49,7 @@ public class TechTree implements ContentList{
}); });
node(itemBridge, () -> { node(itemBridge, () -> {
node(titaniumConveyor, () -> { node(titaniumConveyor, Seq.with(new SectorComplete(craters)), () -> {
node(phaseConveyor, () -> { node(phaseConveyor, () -> {
node(massDriver, () -> { node(massDriver, () -> {
@@ -108,7 +110,7 @@ public class TechTree implements ContentList{
}); });
node(graphitePress, () -> { node(graphitePress, () -> {
node(pneumaticDrill, () -> { node(pneumaticDrill, Seq.with(new SectorComplete(frozenForest)), () -> {
node(cultivator, Seq.with(new SectorComplete(biomassFacility)), () -> { node(cultivator, Seq.with(new SectorComplete(biomassFacility)), () -> {
}); });
@@ -234,7 +236,7 @@ public class TechTree implements ContentList{
}); });
}); });
node(steamGenerator, () -> { node(steamGenerator, Seq.with(new SectorComplete(craters)), () -> {
node(thermalGenerator, () -> { node(thermalGenerator, () -> {
node(differentialGenerator, () -> { node(differentialGenerator, () -> {
node(thoriumReactor, Seq.with(new Research(Liquids.cryofluid)), () -> { node(thoriumReactor, Seq.with(new Research(Liquids.cryofluid)), () -> {
@@ -291,7 +293,7 @@ public class TechTree implements ContentList{
node(salvo, () -> { node(salvo, () -> {
node(swarmer, () -> { node(swarmer, () -> {
node(cyclone, () -> { node(cyclone, () -> {
node(spectre, () -> { node(spectre, Seq.with(new SectorComplete(nuclearComplex)), () -> {
}); });
}); });
@@ -321,8 +323,8 @@ public class TechTree implements ContentList{
}); });
node(lancer, () -> { node(lancer, () -> {
node(foreshadow, () -> {
node(meltdown, () -> { node(meltdown, () -> {
node(foreshadow, () -> {
}); });
}); });
@@ -417,7 +419,7 @@ public class TechTree implements ContentList{
}); });
node(additiveReconstructor, Seq.with(new SectorComplete(biomassFacility)), () -> { node(additiveReconstructor, Seq.with(new SectorComplete(biomassFacility)), () -> {
node(multiplicativeReconstructor, () -> { node(multiplicativeReconstructor, Seq.with(new SectorComplete(overgrowth)), () -> {
node(exponentialReconstructor, () -> { node(exponentialReconstructor, () -> {
node(tetrativeReconstructor, () -> { node(tetrativeReconstructor, () -> {
}); });
@@ -468,10 +470,26 @@ public class TechTree implements ContentList{
new Research(thermalGenerator), new Research(thermalGenerator),
new Research(thoriumReactor) new Research(thoriumReactor)
), () -> { ), () -> {
node(planetaryTerminal, Seq.with(
new SectorComplete(desolateRift),
new SectorComplete(nuclearComplex),
new SectorComplete(overgrowth),
new SectorComplete(extractionOutpost),
new SectorComplete(saltFlats),
new Research(risso),
new Research(minke),
new Research(bryde),
new Research(spectre),
new Research(launchPad),
new Research(impactReactor),
new Research(additiveReconstructor),
new Research(exponentialReconstructor)
), () -> {
}); });
}); });
}); });
});
node(extractionOutpost, Seq.with( node(extractionOutpost, Seq.with(
new SectorComplete(stainedMountains), new SectorComplete(stainedMountains),

View File

@@ -17,11 +17,13 @@ import static mindustry.Vars.*;
public class UnitTypes implements ContentList{ public class UnitTypes implements ContentList{
//region definitions //region definitions
//(the wall of shame - should fix the legacy stuff eventually...)
//mech //mech
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign; public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
//mech + builder + miner //mech
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class}) UnitType nova, pulsar, quasar; public static @EntityDef(value = {Unitc.class, Mechc.class}, legacy = true) UnitType nova, pulsar, quasar;
//mech //mech
public static @EntityDef({Unitc.class, Mechc.class}) UnitType vela; public static @EntityDef({Unitc.class, Mechc.class}) UnitType vela;
@@ -29,29 +31,29 @@ public class UnitTypes implements ContentList{
//legs //legs
public static @EntityDef({Unitc.class, Legsc.class}) UnitType corvus, atrax; public static @EntityDef({Unitc.class, Legsc.class}) UnitType corvus, atrax;
//legs + building //legs
public static @EntityDef({Unitc.class, Legsc.class, Builderc.class}) UnitType spiroct, arkyid, toxopid; public static @EntityDef(value = {Unitc.class, Legsc.class}, legacy = true) UnitType spiroct, arkyid, toxopid;
//air (no special traits) //air
public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra; public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra;
//air, legacy mining //air
public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono; public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono;
//air + building + mining //air
public static @EntityDef({Unitc.class, Builderc.class}) UnitType poly; public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType poly;
//air + building + mining + payload //air + payload
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class}) UnitType mega; public static @EntityDef({Unitc.class, Payloadc.class}) UnitType mega;
//air + building + payload //air + payload
public static @EntityDef(value = {Unitc.class, Builderc.class, Payloadc.class}, legacy = true) UnitType quad; public static @EntityDef(value = {Unitc.class, Payloadc.class}, legacy = true) UnitType quad;
//air + building + payload //air + payload + ammo distribution
public static @EntityDef({Unitc.class, Builderc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct; public static @EntityDef({Unitc.class, Payloadc.class, AmmoDistributec.class}) UnitType oct;
//air + building + mining //air
public static @EntityDef({Unitc.class, Builderc.class}) UnitType alpha, beta, gamma; public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType alpha, beta, gamma;
//water //water
public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType risso, minke, bryde, sei, omura; public static @EntityDef({Unitc.class, WaterMovec.class}) UnitType risso, minke, bryde, sei, omura;
@@ -111,7 +113,7 @@ public class UnitTypes implements ContentList{
}}; }};
fortress = new UnitType("fortress"){{ fortress = new UnitType("fortress"){{
speed = 0.38f; speed = 0.39f;
hitSize = 13f; hitSize = 13f;
rotateSpeed = 3f; rotateSpeed = 3f;
targetAir = false; targetAir = false;
@@ -136,7 +138,7 @@ public class UnitTypes implements ContentList{
collides = true; collides = true;
collidesTiles = true; collidesTiles = true;
splashDamageRadius = 24f; splashDamageRadius = 24f;
splashDamage = 38f; splashDamage = 45f;
backColor = Pal.bulletYellowBack; backColor = Pal.bulletYellowBack;
frontColor = Pal.bulletYellow; frontColor = Pal.bulletYellow;
}}; }};
@@ -419,6 +421,7 @@ public class UnitTypes implements ContentList{
armor = 7f; armor = 7f;
canBoost = true; canBoost = true;
landShake = 4f; landShake = 4f;
immunities = ObjectSet.with(StatusEffects.burning);
commandLimit = 8; commandLimit = 8;
@@ -431,7 +434,7 @@ public class UnitTypes implements ContentList{
firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f; firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f;
reload = 320f; reload = 160f;
recoil = 0f; recoil = 0f;
chargeSound = Sounds.lasercharge2; chargeSound = Sounds.lasercharge2;
shootSound = Sounds.beam; shootSound = Sounds.beam;
@@ -450,7 +453,7 @@ public class UnitTypes implements ContentList{
shootEffect = Fx.greenLaserChargeSmall; shootEffect = Fx.greenLaserChargeSmall;
incendChance = 0.05f; incendChance = 0.075f;
incendSpread = 5f; incendSpread = 5f;
incendAmount = 1; incendAmount = 1;
@@ -470,7 +473,6 @@ public class UnitTypes implements ContentList{
mineTier = 1; mineTier = 1;
hitSize = 29f; hitSize = 29f;
health = 18000f; health = 18000f;
buildSpeed = 1.7f;
armor = 9f; armor = 9f;
landShake = 1.5f; landShake = 1.5f;
rotateSpeed = 1.5f; rotateSpeed = 1.5f;
@@ -700,6 +702,7 @@ public class UnitTypes implements ContentList{
rippleScale = 2f; rippleScale = 2f;
legSpeed = 0.2f; legSpeed = 0.2f;
ammoType = AmmoTypes.power; ammoType = AmmoTypes.power;
buildSpeed = 1f;
legSplashDamage = 32; legSplashDamage = 32;
legSplashRange = 30; legSplashRange = 30;
@@ -802,6 +805,7 @@ public class UnitTypes implements ContentList{
rippleScale = 3f; rippleScale = 3f;
legSpeed = 0.19f; legSpeed = 0.19f;
ammoType = AmmoTypes.powerHigh; ammoType = AmmoTypes.powerHigh;
buildSpeed = 1f;
legSplashDamage = 80; legSplashDamage = 80;
legSplashRange = 60; legSplashRange = 60;
@@ -942,7 +946,7 @@ public class UnitTypes implements ContentList{
engineOffset = 7.8f; engineOffset = 7.8f;
range = 140f; range = 140f;
faceTarget = false; faceTarget = false;
armor = 4f; armor = 3f;
targetFlag = BlockFlag.factory; targetFlag = BlockFlag.factory;
commandLimit = 5; commandLimit = 5;
@@ -950,7 +954,7 @@ public class UnitTypes implements ContentList{
minShootVelocity = 0.75f; minShootVelocity = 0.75f;
x = 3f; x = 3f;
shootY = 0f; shootY = 0f;
reload = 11f; reload = 12f;
shootCone = 180f; shootCone = 180f;
ejectEffect = Fx.none; ejectEffect = Fx.none;
inaccuracy = 15f; inaccuracy = 15f;
@@ -1466,7 +1470,7 @@ public class UnitTypes implements ContentList{
shake = 1.5f; shake = 1.5f;
ejectEffect = Fx.casing2; ejectEffect = Fx.casing2;
shootSound = Sounds.bang; shootSound = Sounds.bang;
bullet = Bullets.artilleryIncendiary; bullet = Bullets.artilleryDense;
}}); }});
}}; }};

View File

@@ -571,19 +571,19 @@ public class NetClient implements ApplicationListener{
BuildPlan[] requests = null; BuildPlan[] requests = null;
if(player.isBuilder()){ if(player.isBuilder()){
//limit to 10 to prevent buffer overflows //limit to 10 to prevent buffer overflows
int usedRequests = Math.min(player.builder().plans().size, 10); int usedRequests = Math.min(player.unit().plans().size, 10);
int totalLength = 0; int totalLength = 0;
//prevent buffer overflow by checking config length //prevent buffer overflow by checking config length
for(int i = 0; i < usedRequests; i++){ for(int i = 0; i < usedRequests; i++){
BuildPlan plan = player.builder().plans().get(i); BuildPlan plan = player.unit().plans().get(i);
if(plan.config instanceof byte[] b){ if(plan.config instanceof byte[] b){
int length = b.length; int length = b.length;
totalLength += length; totalLength += length;
} }
if(totalLength > 2048){ if(totalLength > 1024){
usedRequests = i + 1; usedRequests = i + 1;
break; break;
} }
@@ -591,7 +591,7 @@ public class NetClient implements ApplicationListener{
requests = new BuildPlan[usedRequests]; requests = new BuildPlan[usedRequests];
for(int i = 0; i < usedRequests; i++){ for(int i = 0; i < usedRequests; i++){
requests[i] = player.builder().plans().get(i); requests[i] = player.unit().plans().get(i);
} }
} }
@@ -607,7 +607,7 @@ public class NetClient implements ApplicationListener{
unit.rotation, unit.rotation,
unit instanceof Mechc m ? m.baseRotation() : 0, unit instanceof Mechc m ? m.baseRotation() : 0,
unit.vel.x, unit.vel.y, unit.vel.x, unit.vel.y,
player.miner().mineTile(), player.unit().mineTile,
player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding, player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding,
requests, requests,
Core.camera.position.x, Core.camera.position.y, Core.camera.position.x, Core.camera.position.y,

View File

@@ -600,8 +600,8 @@ public class NetServer implements ApplicationListener{
player.unit().aim(pointerX, pointerY); player.unit().aim(pointerX, pointerY);
if(player.isBuilder()){ if(player.isBuilder()){
player.builder().clearBuilding(); player.unit().clearBuilding();
player.builder().updateBuilding(building); player.unit().updateBuilding(building);
if(requests != null){ if(requests != null){
for(BuildPlan req : requests){ for(BuildPlan req : requests){
@@ -625,14 +625,12 @@ public class NetServer implements ApplicationListener{
con.rejectedRequests.add(req); con.rejectedRequests.add(req);
continue; continue;
} }
player.builder().plans().addLast(req); player.unit().plans().addLast(req);
} }
} }
} }
if(player.isMiner()){ player.unit().mineTile = mining;
player.miner().mineTile(mining);
}
con.rejectedRequests.clear(); con.rejectedRequests.clear();

View File

@@ -124,7 +124,7 @@ public class Damage{
//try to heal the tile //try to heal the tile
if(collide && hitter.type.collides(hitter, tile)){ if(collide && hitter.type.collides(hitter, tile)){
hitter.type.hitTile(hitter, tile, 0f); hitter.type.hitTile(hitter, tile, 0f, false);
} }
}; };

View File

@@ -161,15 +161,17 @@ public abstract class BulletType extends Content{
return healPercent <= 0.001f || tile.team != bullet.team || tile.healthf() < 1f; return healPercent <= 0.001f || tile.team != bullet.team || tile.healthf() < 1f;
} }
public void hitTile(Bullet b, Building tile, float initialHealth){ /** If direct is false, this is an indirect hit and the tile was already damaged.
if(makeFire && tile.team != b.team){ * TODO this is a mess. */
Fires.create(tile.tile); public void hitTile(Bullet b, Building build, float initialHealth, boolean direct){
if(makeFire && build.team != b.team){
Fires.create(build.tile);
} }
if(healPercent > 0f && tile.team == b.team && !(tile.block instanceof ConstructBlock)){ if(healPercent > 0f && build.team == b.team && !(build.block instanceof ConstructBlock)){
Fx.healBlockFull.at(tile.x, tile.y, tile.block.size, Pal.heal); Fx.healBlockFull.at(build.x, build.y, build.block.size, Pal.heal);
tile.heal(healPercent / 100f * tile.maxHealth()); build.heal(healPercent / 100f * build.maxHealth());
}else if(tile.team != b.team){ }else if(build.team != b.team && direct){
hit(b); hit(b);
} }
} }

View File

@@ -54,7 +54,7 @@ public class RailBulletType extends BulletType{
} }
@Override @Override
public void hitTile(Bullet b, Building tile, float initialHealth){ public void hitTile(Bullet b, Building build, float initialHealth, boolean direct){
handle(b, tile, initialHealth); handle(b, build, initialHealth);
} }
} }

View File

@@ -13,6 +13,7 @@ import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.*; import mindustry.world.blocks.*;
import mindustry.world.blocks.ConstructBlock.*; import mindustry.world.blocks.ConstructBlock.*;
@@ -22,17 +23,22 @@ import java.util.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@Component @Component
abstract class BuilderComp implements Unitc{ abstract class BuilderComp implements Posc, Teamc, Rotc{
static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()}; static final Vec2[] vecs = new Vec2[]{new Vec2(), new Vec2(), new Vec2(), new Vec2()};
@Import float x, y, rotation; @Import float x, y, rotation;
@Import UnitType type;
@SyncLocal Queue<BuildPlan> plans = new Queue<>(1); @SyncLocal Queue<BuildPlan> plans = new Queue<>(1);
@SyncLocal transient boolean updateBuilding = true; @SyncLocal transient boolean updateBuilding = true;
public boolean canBuild(){
return type.buildSpeed > 0;
}
@Override @Override
public void update(){ public void update(){
if(!updateBuilding) return; if(!updateBuilding || !canBuild()) return;
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange; float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : buildingRange;
boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources; boolean infinite = state.rules.infiniteResources || team().rules().infiniteResources;
@@ -102,9 +108,9 @@ abstract class BuilderComp implements Unitc{
ConstructBuild entity = tile.bc(); ConstructBuild entity = tile.bc();
if(current.breaking){ if(current.breaking){
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier); entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier);
}else{ }else{
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type().buildSpeed * state.rules.buildSpeedMultiplier, current.config); entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * state.rules.buildSpeedMultiplier, current.config);
} }
current.stuck = Mathf.equal(current.progress, entity.progress); current.stuck = Mathf.equal(current.progress, entity.progress);
@@ -161,6 +167,8 @@ abstract class BuilderComp implements Unitc{
/** Add another build requests to the queue, if it doesn't exist there yet. */ /** Add another build requests to the queue, if it doesn't exist there yet. */
void addBuild(BuildPlan place, boolean tail){ void addBuild(BuildPlan place, boolean tail){
if(!canBuild()) return;
BuildPlan replace = null; BuildPlan replace = null;
for(BuildPlan request : plans){ for(BuildPlan request : plans){
if(request.x == place.x && request.y == place.y){ if(request.x == place.x && request.y == place.y){
@@ -196,9 +204,8 @@ abstract class BuilderComp implements Unitc{
return plans.size == 0 ? null : plans.first(); return plans.size == 0 ? null : plans.first();
} }
@Override
public void draw(){ public void draw(){
if(!isBuilding() || !updateBuilding) return; if(!isBuilding() || !updateBuilding || !canBuild()) return;
//TODO check correctness //TODO check correctness
Draw.z(Layer.flyingUnit); Draw.z(Layer.flyingUnit);

View File

@@ -1122,7 +1122,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
/** Returns whether or not a hand cursor should be shown over this block. */ /** Returns whether or not a hand cursor should be shown over this block. */
public Cursor getCursor(){ public Cursor getCursor(){
return block.configurable ? SystemCursor.hand : SystemCursor.arrow; return block.configurable && team == player.team() ? SystemCursor.hand : SystemCursor.arrow;
} }
/** /**

View File

@@ -142,7 +142,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
} }
} }
type.hitTile(self(), tile, health); type.hitTile(self(), tile, health, true);
return !type.pierceBuilding; return !type.pierceBuilding;
} }

View File

@@ -32,7 +32,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
} }
boolean mining(){ boolean mining(){
return mineTile != null && !(((Object)this) instanceof Builderc b && b.activelyBuilding()); return mineTile != null && !this.<Unit>self().activelyBuilding();
} }
public boolean validMine(Tile tile, boolean checkDst){ public boolean validMine(Tile tile, boolean checkDst){
@@ -44,6 +44,10 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{
return validMine(tile, true); return validMine(tile, true);
} }
public boolean canMine(){
return type.mineSpeed > 0;
}
@Override @Override
public void update(){ public void update(){
Building core = closestCore(); Building core = closestCore();

View File

@@ -48,11 +48,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
transient float textFadeTime; transient float textFadeTime;
public boolean isBuilder(){ public boolean isBuilder(){
return unit instanceof Builderc; return unit.canBuild();
}
public boolean isMiner(){
return unit instanceof Minerc;
} }
public @Nullable CoreBuild closestCore(){ public @Nullable CoreBuild closestCore(){
@@ -164,14 +160,6 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
return unit; return unit;
} }
public Minerc miner(){
return !(unit instanceof Minerc) ? Nulls.miner : (Minerc)unit;
}
public Builderc builder(){
return !(unit instanceof Builderc) ? Nulls.builder : (Builderc)unit;
}
public void unit(Unit unit){ public void unit(Unit unit){
if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead."); if(unit == null) throw new IllegalArgumentException("Unit cannot be null. Use clearUnit() instead.");
if(this.unit == unit) return; if(this.unit == unit) return;

View File

@@ -31,7 +31,7 @@ import mindustry.world.blocks.payloads.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@Component(base = true) @Component(base = true)
abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc{ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, Itemsc, Rotc, Unitc, Weaponsc, Drawc, Boundedc, Syncc, Shieldc, Commanderc, Displayable, Senseable, Ranged, Minerc, Builderc{
@Import boolean hovering, dead; @Import boolean hovering, dead;
@Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed; @Import float x, y, rotation, elevation, maxHealth, drag, armor, hitSize, health, ammo, minFormationSpeed;
@@ -88,8 +88,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
/** @return where the unit wants to look at. */ /** @return where the unit wants to look at. */
public float prefRotation(){ public float prefRotation(){
if(this instanceof Builderc builder && builder.activelyBuilding()){ if(activelyBuilding()){
return angleTo(builder.buildPlan()); return angleTo(buildPlan());
}else if(mineTile() != null){ }else if(mineTile() != null){
return angleTo(mineTile()); return angleTo(mineTile());
}else if(moving()){ }else if(moving()){

View File

@@ -117,6 +117,7 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc, Velc, Statusc{
}else{ }else{
mount.bullet.rotation(weaponRotation + 90); mount.bullet.rotation(weaponRotation + 90);
mount.bullet.set(shootX, shootY); mount.bullet.set(shootX, shootY);
mount.reload = weapon.reload;
vel.add(Tmp.v1.trns(rotation + 180f, mount.bullet.type.recoil)); vel.add(Tmp.v1.trns(rotation + 180f, mount.bullet.type.recoil));
if(weapon.shootSound != Sounds.none && !headless){ if(weapon.shootSound != Sounds.none && !headless){
if(mount.sound == null) mount.sound = new SoundLoop(weapon.shootSound, 1f); if(mount.sound == null) mount.sound = new SoundLoop(weapon.shootSound, 1f);

View File

@@ -43,6 +43,8 @@ public class SectorInfo{
public boolean waves = true; public boolean waves = true;
/** Whether attack mode is enabled here. */ /** Whether attack mode is enabled here. */
public boolean attack = false; public boolean attack = false;
/** Whether this sector has any enemy spawns. */
public boolean hasSpawns = true;
/** Wave # from state */ /** Wave # from state */
public int wave = 1, winWave = -1; public int wave = 1, winWave = -1;
/** Waves this sector can survive if under attack. Based on wave in info. <0 means uncalculated. */ /** Waves this sector can survive if under attack. Based on wave in info. <0 means uncalculated. */
@@ -168,6 +170,7 @@ public class SectorInfo{
secondsPassed = 0; secondsPassed = 0;
wavesPassed = 0; wavesPassed = 0;
damage = 0; damage = 0;
hasSpawns = spawner.countSpawns() > 0;
if(state.rules.sector != null){ if(state.rules.sector != null){
state.rules.sector.saveInfo(); state.rules.sector.saveInfo();

View File

@@ -206,7 +206,7 @@ public class Universe{
} }
//queue random invasions //queue random invasions
if(!sector.isAttacked() && turn > invasionGracePeriod){ if(!sector.isAttacked() && turn > invasionGracePeriod && sector.info.hasSpawns){
//invasion chance depends on # of nearby bases //invasion chance depends on # of nearby bases
if(Mathf.chance(baseInvasionChance * sector.near().count(Sector::hasEnemyBase))){ if(Mathf.chance(baseInvasionChance * sector.near().count(Sector::hasEnemyBase))){
int waveMax = Math.max(sector.info.winWave, sector.isBeingPlayed() ? state.wave : sector.info.wave + sector.info.wavesPassed) + Mathf.random(2, 5) * 5; int waveMax = Math.max(sector.info.winWave, sector.isBeingPlayed() ? state.wave : sector.info.wave + sector.info.wavesPassed) + Mathf.random(2, 5) * 5;

View File

@@ -28,7 +28,7 @@ public class OverlayRenderer{
if(player.dead()) return; if(player.dead()) return;
if(player.isBuilder()){ if(player.isBuilder()){
player.builder().drawBuildRequests(); player.unit().drawBuildRequests();
} }
input.drawBottom(); input.drawBottom();

View File

@@ -59,7 +59,7 @@ public class DesktopInput extends InputHandler{
group.fill(t -> { group.fill(t -> {
t.bottom(); t.bottom();
t.visible(() -> { t.visible(() -> {
t.color.a = Mathf.lerpDelta(t.color.a, player.builder().isBuilding() ? 1f : 0f, 0.15f); t.color.a = Mathf.lerpDelta(t.color.a, player.unit().isBuilding() ? 1f : 0f, 0.15f);
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && t.color.a > 0.01f; return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && t.color.a > 0.01f;
}); });
@@ -290,7 +290,7 @@ public class DesktopInput extends InputHandler{
cursorType = cursor.build.getCursor(); cursorType = cursor.build.getCursor();
} }
if(isPlacing() || !selectRequests.isEmpty()){ if((isPlacing() && player.isBuilder()) || !selectRequests.isEmpty()){
cursorType = SystemCursor.hand; cursorType = SystemCursor.hand;
} }
@@ -366,7 +366,7 @@ public class DesktopInput extends InputHandler{
int rawCursorX = World.toTile(Core.input.mouseWorld().x), rawCursorY = World.toTile(Core.input.mouseWorld().y); int rawCursorX = World.toTile(Core.input.mouseWorld().x), rawCursorY = World.toTile(Core.input.mouseWorld().y);
// automatically pause building if the current build queue is empty // automatically pause building if the current build queue is empty
if(Core.settings.getBool("buildautopause") && isBuilding && !player.builder().isBuilding()){ if(Core.settings.getBool("buildautopause") && isBuilding && !player.unit().isBuilding()){
isBuilding = false; isBuilding = false;
buildWasAutoPaused = true; buildWasAutoPaused = true;
} }
@@ -383,12 +383,12 @@ public class DesktopInput extends InputHandler{
schematicY += shiftY; schematicY += shiftY;
} }
if(Core.input.keyTap(Binding.deselect)){ if(Core.input.keyTap(Binding.deselect) && !isPlacing()){
player.miner().mineTile(null); player.unit().mineTile = null;
} }
if(Core.input.keyTap(Binding.clear_building)){ if(Core.input.keyTap(Binding.clear_building)){
player.builder().clearBuilding(); player.unit().clearBuilding();
} }
if(Core.input.keyTap(Binding.schematic_select) && !Core.scene.hasKeyboard() && mode != breaking){ if(Core.input.keyTap(Binding.schematic_select) && !Core.scene.hasKeyboard() && mode != breaking){
@@ -480,8 +480,8 @@ public class DesktopInput extends InputHandler{
deleting = true; deleting = true;
}else if(selected != null){ }else if(selected != null){
//only begin shooting if there's no cursor event //only begin shooting if there's no cursor event
if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !player.builder().activelyBuilding() && !droppingItem && if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !player.unit().activelyBuilding() && !droppingItem &&
!tryBeginMine(selected) && player.miner().mineTile() == null && !Core.scene.hasKeyboard()){ !tryBeginMine(selected) && player.unit().mineTile == null && !Core.scene.hasKeyboard()){
player.shooting = shouldShoot; player.shooting = shouldShoot;
} }
}else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine }else if(!Core.scene.hasKeyboard()){ //if it's out of bounds, shooting is just fine
@@ -506,7 +506,7 @@ public class DesktopInput extends InputHandler{
if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){ if(Core.input.keyDown(Binding.select) && mode == none && !isPlacing() && deleting){
BuildPlan req = getRequest(cursorX, cursorY); BuildPlan req = getRequest(cursorX, cursorY);
if(req != null && req.breaking){ if(req != null && req.breaking){
player.builder().plans().remove(req); player.unit().plans().remove(req);
} }
}else{ }else{
deleting = false; deleting = false;
@@ -547,7 +547,7 @@ public class DesktopInput extends InputHandler{
if(sreq != null){ if(sreq != null){
if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){ if(getRequest(sreq.x, sreq.y, sreq.block.size, sreq) != null){
player.builder().plans().remove(sreq, true); player.unit().plans().remove(sreq, true);
} }
sreq = null; sreq = null;
} }

View File

@@ -169,7 +169,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
@Remote(variants = Variant.one) @Remote(variants = Variant.one)
public static void removeQueueBlock(int x, int y, boolean breaking){ public static void removeQueueBlock(int x, int y, boolean breaking){
player.builder().removeBuild(x, y, breaking); player.unit().removeBuild(x, y, breaking);
} }
@Remote(targets = Loc.both, called = Loc.server) @Remote(targets = Loc.both, called = Loc.server)
@@ -383,7 +383,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public Eachable<BuildPlan> allRequests(){ public Eachable<BuildPlan> allRequests(){
return cons -> { return cons -> {
for(BuildPlan request : player.builder().plans()) cons.get(request); for(BuildPlan request : player.unit().plans()) cons.get(request);
for(BuildPlan request : selectRequests) cons.get(request); for(BuildPlan request : selectRequests) cons.get(request);
for(BuildPlan request : lineRequests) cons.get(request); for(BuildPlan request : lineRequests) cons.get(request);
}; };
@@ -401,7 +401,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
player.typing = ui.chatfrag.shown(); player.typing = ui.chatfrag.shown();
if(player.isBuilder()){ if(player.isBuilder()){
player.builder().updateBuilding(isBuilding); player.unit().updateBuilding(isBuilding);
} }
if(player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && player.unit().ammo <= 0){ if(player.shooting && !wasShooting && player.unit().hasWeapons() && state.rules.unitAmmo && player.unit().ammo <= 0){
@@ -653,7 +653,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
return r2.overlaps(r1); return r2.overlaps(r1);
}; };
for(BuildPlan req : player.builder().plans()){ for(BuildPlan req : player.unit().plans()){
if(test.get(req)) return req; if(test.get(req)) return req;
} }
@@ -678,7 +678,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Draw.color(Pal.remove); Draw.color(Pal.remove);
Lines.stroke(1f); Lines.stroke(1f);
for(BuildPlan req : player.builder().plans()){ for(BuildPlan req : player.unit().plans()){
if(req.breaking) continue; if(req.breaking) continue;
if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){ if(req.bounds(Tmp.r2).overlaps(Tmp.r1)){
drawBreaking(req); drawBreaking(req);
@@ -740,7 +740,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
for(BuildPlan req : requests){ for(BuildPlan req : requests){
if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){ if(req.block != null && validPlace(req.x, req.y, req.block, req.rotation)){
BuildPlan copy = req.copy(); BuildPlan copy = req.copy();
player.builder().addBuild(copy); player.unit().addBuild(copy);
} }
} }
} }
@@ -778,7 +778,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
/** Remove everything from the queue in a selection. */ /** Remove everything from the queue in a selection. */
protected void removeSelection(int x1, int y1, int x2, int y2, boolean flush){ protected void removeSelection(int x1, int y1, int x2, int y2, boolean flush){
removeSelection(x1, y1, x2, y2, false, maxLength); removeSelection(x1, y1, x2, y2, flush, maxLength);
} }
/** Remove everything from the queue in a selection. */ /** Remove everything from the queue in a selection. */
@@ -804,7 +804,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//remove build requests //remove build requests
Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize); Tmp.r1.set(result.x * tilesize, result.y * tilesize, (result.x2 - result.x) * tilesize, (result.y2 - result.y) * tilesize);
Iterator<BuildPlan> it = player.builder().plans().iterator(); Iterator<BuildPlan> it = player.unit().plans().iterator();
while(it.hasNext()){ while(it.hasNext()){
BuildPlan req = it.next(); BuildPlan req = it.next();
if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){ if(!req.breaking && req.bounds(Tmp.r2).overlaps(Tmp.r1)){
@@ -925,7 +925,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
boolean tryBeginMine(Tile tile){ boolean tryBeginMine(Tile tile){
if(canMine(tile)){ if(canMine(tile)){
//if a block is clicked twice, reset it //if a block is clicked twice, reset it
player.miner().mineTile(player.miner().mineTile() == tile ? null : tile); player.unit().mineTile = player.unit().mineTile == tile ? null : tile;
return true; return true;
} }
return false; return false;
@@ -934,7 +934,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
boolean canMine(Tile tile){ boolean canMine(Tile tile){
return !Core.scene.hasMouse() return !Core.scene.hasMouse()
&& tile.drop() != null && tile.drop() != null
&& player.miner().validMine(tile) && player.unit().validMine(tile)
&& !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null) && !(tile.floor().playerUnmineable && tile.overlay().itemDrop == null)
&& player.unit().acceptsItem(tile.drop()) && player.unit().acceptsItem(tile.drop())
&& tile.block() == Blocks.air; && tile.block() == Blocks.air;
@@ -1044,7 +1044,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
} }
public boolean canShoot(){ public boolean canShoot(){
return block == null && !onConfigurable() && !isDroppingItem() && !player.builder().activelyBuilding() && return block == null && !onConfigurable() && !isDroppingItem() && !player.unit().activelyBuilding() &&
!(player.unit() instanceof Mechc && player.unit().isFlying()); !(player.unit() instanceof Mechc && player.unit().isFlying());
} }
@@ -1090,7 +1090,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
} }
public boolean validPlace(int x, int y, Block type, int rotation, BuildPlan ignore){ public boolean validPlace(int x, int y, Block type, int rotation, BuildPlan ignore){
for(BuildPlan req : player.builder().plans()){ for(BuildPlan req : player.unit().plans()){
if(req != ignore if(req != ignore
&& !req.breaking && !req.breaking
&& req.block.bounds(req.x, req.y, Tmp.r1).overlaps(type.bounds(x, y, Tmp.r2)) && req.block.bounds(req.x, req.y, Tmp.r1).overlaps(type.bounds(x, y, Tmp.r2))
@@ -1108,15 +1108,15 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public void placeBlock(int x, int y, Block block, int rotation){ public void placeBlock(int x, int y, Block block, int rotation){
BuildPlan req = getRequest(x, y); BuildPlan req = getRequest(x, y);
if(req != null){ if(req != null){
player.builder().plans().remove(req); player.unit().plans().remove(req);
} }
player.builder().addBuild(new BuildPlan(x, y, rotation, block, block.nextConfig())); player.unit().addBuild(new BuildPlan(x, y, rotation, block, block.nextConfig()));
} }
public void breakBlock(int x, int y){ public void breakBlock(int x, int y){
Tile tile = world.tile(x, y); Tile tile = world.tile(x, y);
if(tile != null && tile.build != null) tile = tile.build.tile; if(tile != null && tile.build != null) tile = tile.build.tile;
player.builder().addBuild(new BuildPlan(tile.x, tile.y)); player.unit().addBuild(new BuildPlan(tile.x, tile.y));
} }
public void drawArrow(Block block, int x, int y, int rotation){ public void drawArrow(Block block, int x, int y, int rotation){

View File

@@ -114,7 +114,7 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
} }
for(BuildPlan req : player.builder().plans()){ for(BuildPlan req : player.unit().plans()){
Tile other = world.tile(req.x, req.y); Tile other = world.tile(req.x, req.y);
if(other == null || req.breaking) continue; if(other == null || req.breaking) continue;
@@ -219,10 +219,10 @@ public class MobileInput extends InputHandler implements GestureListener{
BuildPlan copy = request.copy(); BuildPlan copy = request.copy();
if(other == null){ if(other == null){
player.builder().addBuild(copy); player.unit().addBuild(copy);
}else if(!other.breaking && other.x == request.x && other.y == request.y && other.block.size == request.block.size){ }else if(!other.breaking && other.x == request.x && other.y == request.y && other.block.size == request.block.size){
player.builder().plans().remove(other); player.unit().plans().remove(other);
player.builder().addBuild(copy); player.unit().addBuild(copy);
} }
} }
@@ -245,10 +245,10 @@ public class MobileInput extends InputHandler implements GestureListener{
Boolp schem = () -> lastSchematic != null && !selectRequests.isEmpty(); Boolp schem = () -> lastSchematic != null && !selectRequests.isEmpty();
group.fill(t -> { group.fill(t -> {
t.visible(() -> (player.builder().isBuilding() || block != null || mode == breaking || !selectRequests.isEmpty()) && !schem.get()); t.visible(() -> (player.unit().isBuilding() || block != null || mode == breaking || !selectRequests.isEmpty()) && !schem.get());
t.bottom().left(); t.bottom().left();
t.button("@cancel", Icon.cancel, () -> { t.button("@cancel", Icon.cancel, () -> {
player.builder().clearBuilding(); player.unit().clearBuilding();
selectRequests.clear(); selectRequests.clear();
mode = none; mode = none;
block = null; block = null;
@@ -914,7 +914,7 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
//update shooting if not building + not mining //update shooting if not building + not mining
if(!player.builder().isBuilding() && player.miner().mineTile() == null){ if(!player.unit().isBuilding() && player.unit().mineTile == null){
//autofire targeting //autofire targeting
if(manualShooting){ if(manualShooting){

View File

@@ -14,6 +14,7 @@ import mindustry.world.*;
/** "Compiles" a sequence of statements into instructions. */ /** "Compiles" a sequence of statements into instructions. */
public class LAssembler{ public class LAssembler{
public static ObjectMap<String, Func<String[], LStatement>> customParsers = new ObjectMap<>(); public static ObjectMap<String, Func<String[], LStatement>> customParsers = new ObjectMap<>();
public static final int maxTokenLength = 40;
private int lastVar; private int lastVar;
/** Maps names to variable IDs. */ /** Maps names to variable IDs. */
@@ -122,7 +123,7 @@ public class LAssembler{
if(c == '"'){ if(c == '"'){
inString = !inString; inString = !inString;
}else if(c == ' ' && !inString){ }else if(c == ' ' && !inString){
tokens.add(line.substring(lastIdx, i)); tokens.add(line.substring(lastIdx, Math.min(i, lastIdx + maxTokenLength)));
lastIdx = i + 1; lastIdx = i + 1;
} }
} }

View File

@@ -321,13 +321,8 @@ public class LExecutor{
((LogicAI)unit.controller()).controller = exec.building(varThis); ((LogicAI)unit.controller()).controller = exec.building(varThis);
//clear old state //clear old state
if(unit instanceof Minerc miner){ unit.mineTile = null;
miner.mineTile(null); unit.clearBuilding();
}
if(unit instanceof Builderc builder){
builder.clearBuilding();
}
return (LogicAI)unit.controller(); return (LogicAI)unit.controller();
} }
@@ -357,12 +352,8 @@ public class LExecutor{
//stop mining/building //stop mining/building
if(type == LUnitControl.stop){ if(type == LUnitControl.stop){
if(unit instanceof Minerc miner){ unit.mineTile = null;
miner.mineTile(null); unit.clearBuilding();
}
if(unit instanceof Builderc build){
build.clearBuilding();
}
} }
} }
case within -> { case within -> {
@@ -390,8 +381,8 @@ public class LExecutor{
} }
case mine -> { case mine -> {
Tile tile = world.tileWorld(x1, y1); Tile tile = world.tileWorld(x1, y1);
if(unit instanceof Minerc miner){ if(unit.canMine()){
miner.mineTile(miner.validMine(tile) ? tile : null); unit.mineTile = unit.validMine(tile) ? tile : null;
} }
} }
case payDrop -> { case payDrop -> {
@@ -432,12 +423,12 @@ public class LExecutor{
} }
} }
case build -> { case build -> {
if(unit instanceof Builderc builder && exec.obj(p3) instanceof Block block){ if(unit.canBuild() && exec.obj(p3) instanceof Block block){
int x = World.toTile(x1), y = World.toTile(y1); int x = World.toTile(x1), y = World.toTile(y1);
int rot = exec.numi(p4); int rot = exec.numi(p4);
//reset state of last request when necessary //reset state of last request when necessary
if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || builder.plans().isEmpty()){ if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || unit.plans.isEmpty()){
ai.plan.progress = 0; ai.plan.progress = 0;
ai.plan.initialized = false; ai.plan.initialized = false;
ai.plan.stuck = false; ai.plan.stuck = false;
@@ -446,11 +437,11 @@ public class LExecutor{
ai.plan.set(x, y, rot, block); ai.plan.set(x, y, rot, block);
ai.plan.config = exec.obj(p5) instanceof Content c ? c : null; ai.plan.config = exec.obj(p5) instanceof Content c ? c : null;
builder.clearBuilding(); unit.clearBuilding();
if(ai.plan.tile() != null){ if(ai.plan.tile() != null){
builder.updateBuilding(true); unit.updateBuilding = true;
builder.addBuild(ai.plan); unit.addBuild(ai.plan);
} }
} }
} }

View File

@@ -40,7 +40,7 @@ public abstract class LStatement{
protected Cell<TextField> field(Table table, String value, Cons<String> setter){ protected Cell<TextField> field(Table table, String value, Cons<String> setter){
return table.field(value, Styles.nodeField, setter) return table.field(value, Styles.nodeField, setter)
.size(144f, 40f).pad(2f).color(table.color).addInputDialog(); .size(144f, 40f).pad(2f).color(table.color).maxTextLength(LAssembler.maxTokenLength).addInputDialog();
} }
protected Cell<TextField> fields(Table table, String desc, String value, Cons<String> setter){ protected Cell<TextField> fields(Table table, String desc, String value, Cons<String> setter){

View File

@@ -80,7 +80,7 @@ public class UnitType extends UnlockableContent{
public int ammoCapacity = -1; public int ammoCapacity = -1;
public AmmoType ammoType = AmmoTypes.copper; public AmmoType ammoType = AmmoTypes.copper;
public int mineTier = -1; public int mineTier = -1;
public float buildSpeed = 1f, mineSpeed = 1f; public float buildSpeed = -1f, mineSpeed = 1f;
public Sound mineSound = Sounds.minebeam; public Sound mineSound = Sounds.minebeam;
public float mineSoundVolume = 0.6f; public float mineSoundVolume = 0.6f;
@@ -225,7 +225,7 @@ public class UnitType extends UnlockableContent{
stats.addPercent(Stat.mineSpeed, mineSpeed); stats.addPercent(Stat.mineSpeed, mineSpeed);
stats.add(Stat.mineTier, new BlockFilterValue(b -> b instanceof Floor f && f.itemDrop != null && f.itemDrop.hardness <= mineTier && !f.playerUnmineable)); stats.add(Stat.mineTier, new BlockFilterValue(b -> b instanceof Floor f && f.itemDrop != null && f.itemDrop.hardness <= mineTier && !f.playerUnmineable));
} }
if(inst instanceof Builderc){ if(buildSpeed > 0){
stats.addPercent(Stat.buildSpeed, buildSpeed); stats.addPercent(Stat.buildSpeed, buildSpeed);
} }
if(inst instanceof Payloadc){ if(inst instanceof Payloadc){
@@ -374,7 +374,7 @@ public class UnitType extends UnlockableContent{
if(stacks != null){ if(stacks != null){
ItemStack[] out = new ItemStack[stacks.length]; ItemStack[] out = new ItemStack[stacks.length];
for(int i = 0; i < out.length; i++){ for(int i = 0; i < out.length; i++){
out[i] = new ItemStack(stacks[i].item, UI.roundAmount((int)(Math.pow(stacks[i].amount, 1.1) * 50))); out[i] = new ItemStack(stacks[i].item, UI.roundAmount((int)(Math.pow(stacks[i].amount, 1.11) * 50)));
} }
return out; return out;

View File

@@ -31,9 +31,13 @@ public class Bar extends Element{
this.fraction = fraction; this.fraction = fraction;
lastValue = value = Mathf.clamp(fraction.get()); lastValue = value = Mathf.clamp(fraction.get());
update(() -> { update(() -> {
try{
this.name = name.get(); this.name = name.get();
this.blinkColor.set(color.get()); this.blinkColor.set(color.get());
setColor(color.get()); setColor(color.get());
}catch(Exception e){ //getting the fraction may involve referring to invalid data
this.name = "";
}
}); });
} }

View File

@@ -95,6 +95,7 @@ public class Fonts{
var region = new TextureRegion(); var region = new TextureRegion();
int code = Iconc.codes.get(name, '\uF8D4'); int code = Iconc.codes.get(name, '\uF8D4');
var glyph = iconLarge.getData().getGlyph((char)code); var glyph = iconLarge.getData().getGlyph((char)code);
if(glyph == null) return Core.atlas.find("error");
region.set(iconLarge.getRegion().texture); region.set(iconLarge.getRegion().texture);
region.set(glyph.u, glyph.v2, glyph.u2, glyph.v); region.set(glyph.u, glyph.v2, glyph.u2, glyph.v);
return region; return region;

View File

@@ -103,6 +103,8 @@ public class LaunchLoadoutDialog extends BaseDialog{
ButtonGroup<Button> group = new ButtonGroup<>(); ButtonGroup<Button> group = new ButtonGroup<>();
selected = universe.getLoadout(core); selected = universe.getLoadout(core);
cont.add(Core.bundle.format("launch.from", sector.name())).row();
cont.pane(t -> { cont.pane(t -> {
int i = 0; int i = 0;

View File

@@ -679,7 +679,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
if(sector.info.wavesSurvived >= 0 && sector.info.wavesSurvived - sector.info.wavesPassed >= 0 && !sector.isBeingPlayed()){ if(sector.info.wavesSurvived >= 0 && sector.info.wavesSurvived - sector.info.wavesPassed >= 0 && !sector.isBeingPlayed()){
int toCapture = sector.info.attack || sector.info.winWave <= 1 ? -1 : sector.info.winWave - (sector.info.wave + sector.info.wavesPassed); int toCapture = sector.info.attack || sector.info.winWave <= 1 ? -1 : sector.info.winWave - (sector.info.wave + sector.info.wavesPassed);
boolean plus = (sector.info.wavesSurvived - sector.info.wavesPassed) >= SectorDamage.maxRetWave - 1; boolean plus = (sector.info.wavesSurvived - sector.info.wavesPassed) >= SectorDamage.maxRetWave - 1;
stable.add("[accent]Survives " + Math.min(sector.info.wavesSurvived - sector.info.wavesPassed, toCapture) + stable.add("[accent]Survives " + Math.min(sector.info.wavesSurvived - sector.info.wavesPassed, toCapture <= 0 ? 200 : 0) +
(plus ? "+" : "") + (toCapture < 0 ? "" : "/" + toCapture) + " waves"); (plus ? "+" : "") + (toCapture < 0 ? "" : "/" + toCapture) + " waves");
stable.row(); stable.row();
} }

View File

@@ -102,7 +102,7 @@ public class PlacementFragment extends Fragment{
Block tryRecipe = tile == null ? null : tile.block instanceof ConstructBlock ? ((ConstructBuild)tile).cblock : tile.block; Block tryRecipe = tile == null ? null : tile.block instanceof ConstructBlock ? ((ConstructBuild)tile).cblock : tile.block;
Object tryConfig = tile == null ? null : tile.config(); Object tryConfig = tile == null ? null : tile.config();
for(BuildPlan req : player.builder().plans()){ for(BuildPlan req : player.unit().plans()){
if(!req.breaking && req.block.bounds(req.x, req.y, Tmp.r1).contains(Core.input.mouseWorld())){ if(!req.breaking && req.block.bounds(req.x, req.y, Tmp.r1).contains(Core.input.mouseWorld())){
tryRecipe = req.block; tryRecipe = req.block;
tryConfig = req.config; tryConfig = req.config;

View File

@@ -179,7 +179,7 @@ public class ConstructBlock extends Block{
if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){ if(control.input.buildWasAutoPaused && !control.input.isBuilding && player.isBuilder()){
control.input.isBuilding = true; control.input.isBuilding = true;
} }
player.builder().addBuild(new BuildPlan(tile.x, tile.y, rotation, cblock, lastConfig), false); player.unit().addBuild(new BuildPlan(tile.x, tile.y, rotation, cblock, lastConfig), false);
} }
} }

View File

@@ -0,0 +1,104 @@
package mindustry.world.blocks.campaign;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.*;
import static mindustry.Vars.*;
public class Accelerator extends Block{
public @Load("launch-arrow") TextureRegion arrowRegion;
public Block launching = Blocks.coreNucleus;
public int[] capacities = new int[content.items().size];
public Accelerator(String name){
super(name);
update = true;
solid = true;
hasItems = true;
itemCapacity = 8000;
configurable = true;
}
@Override
public void init(){
for(ItemStack stack : launching.requirements){
capacities[stack.item.id] = stack.amount;
}
consumes.items(launching.requirements);
super.init();
}
public class AcceleratorBuild extends Building{
@Override
public void draw(){
super.draw();
for(int l = 0; l < 4; l++){
float length = 7f + l * 5f;
Draw.color(team.color, Pal.darkMetal, Mathf.absin(Time.time() + l*50f, 10f, 1f));
for(int i = 0; i < 4; i++){
float rot = i*90f + 45f;
Draw.rect(arrowRegion, x + Angles.trnsx(rot, length), y + Angles.trnsy(rot, length), rot + 180f);
}
}
float rad = size * tilesize / 2f * 0.74f;
float scl = 2f;
Draw.z(Layer.bullet - 0.0001f);
Lines.stroke(1.75f, Pal.accent);
Lines.square(x, y, rad * 1.22f, 45f);
Lines.stroke(3f, Pal.accent);
Lines.square(x, y, rad, Time.time() / scl);
Lines.square(x, y, rad, -Time.time() / scl);
Draw.color(team.color);
for(int i = 0; i < 4; i++){
float rot = i*90f + 45f + (-Time.time()/3f)%360f;
float length = 26f;
Draw.rect(arrowRegion, x + Angles.trnsx(rot, length), y + Angles.trnsy(rot, length), rot + 180f);
}
Draw.reset();
}
@Override
public Cursor getCursor(){
return !state.isCampaign() || !consValid() ? SystemCursor.arrow : super.getCursor();
}
@Override
public void buildConfiguration(Table table){
deselect();
if(!state.isCampaign() || !consValid()) return;
ui.showInfo("@indev.campaign");
}
@Override
public int getMaximumAccepted(Item item){
return capacities[item.id];
}
@Override
public boolean acceptItem(Building source, Item item){
return items.get(item) < getMaximumAccepted(item);
}
}
}

View File

@@ -1,6 +1,8 @@
package mindustry.world.blocks.campaign; package mindustry.world.blocks.campaign;
import arc.*; import arc.*;
import arc.Graphics.*;
import arc.Graphics.Cursor.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
@@ -54,6 +56,11 @@ public class LaunchPad extends Block{
public class LaunchPadBuild extends Building{ public class LaunchPadBuild extends Building{
@Override
public Cursor getCursor(){
return !state.isCampaign() ? SystemCursor.arrow : super.getCursor();
}
@Override @Override
public void draw(){ public void draw(){
super.draw(); super.draw();

View File

@@ -66,7 +66,7 @@ public abstract class Turret extends ReloadTurret{
protected Vec2 tr = new Vec2(); protected Vec2 tr = new Vec2();
protected Vec2 tr2 = new Vec2(); protected Vec2 tr2 = new Vec2();
public @Load(value = "base-@", fallback = "block-@size") TextureRegion baseRegion; public @Load(value = "@-base", fallback = "block-@size") TextureRegion baseRegion;
public @Load("@-heat") TextureRegion heatRegion; public @Load("@-heat") TextureRegion heatRegion;
public Cons<TurretBuild> drawer = tile -> Draw.rect(region, tile.x + tr2.x, tile.y + tr2.y, tile.rotation - 90); public Cons<TurretBuild> drawer = tile -> Draw.rect(region, tile.x + tr2.x, tile.y + tr2.y, tile.rotation - 90);

View File

@@ -305,6 +305,8 @@ public class LogicBlock extends Block{
} }
} }
asm.putConst("@mapw", world.width());
asm.putConst("@maph", world.height());
asm.putConst("@links", executor.links.length); asm.putConst("@links", executor.links.length);
asm.putConst("@ipt", instructionsPerTick); asm.putConst("@ipt", instructionsPerTick);

View File

@@ -57,6 +57,7 @@ public interface Payload{
return (T)payload; return (T)payload;
}else if(type == payloadUnit){ }else if(type == payloadUnit){
byte id = read.b(); byte id = read.b();
if(EntityMapping.map(id) == null) throw new RuntimeException("No type with ID " + id + " found.");
Unit unit = (Unit)EntityMapping.map(id).get(); Unit unit = (Unit)EntityMapping.map(id).get();
unit.read(read); unit.read(read);
return (T)new UnitPayload(unit); return (T)new UnitPayload(unit);

View File

@@ -63,6 +63,8 @@ public class CoreBlock extends StorageBlock{
CoreBlock block = (CoreBlock)tile.block(); CoreBlock block = (CoreBlock)tile.block();
Fx.spawn.at(entity); Fx.spawn.at(entity);
player.set(entity);
if(!net.client()){ if(!net.client()){
Unit unit = block.unitType.create(tile.team()); Unit unit = block.unitType.create(tile.team());
unit.set(entity); unit.set(entity);

View File

@@ -0,0 +1,5 @@
- Fixed research not using resources
- Fixed capturing other sectors in campaign counting as a capture in current sector
- Fixed incorrect shots/sec for turrets
- Fixed resources being unlocked in custom games
- Made campaign co-op games automatically send maps upon switching sectors instead of disconnecting

View File

@@ -0,0 +1,5 @@
- Исправлено исследование не использующее ресурсы
- Исправлен подсчёт захвата других секторов в кампании как номер текущего сектора
- Исправлено неправильное значение выстрелы/секунду у турелей
- Исправлены уже разблокированные ресурсы в пользовательских играх
- Сделана автоматическая отправка карт вместо отключения при переключении секторов в режиме совместного прохождения кампании

View File

@@ -1 +1 @@
Заводостроительная игра-песочница в жанре защита башен. Заводостроительная игра-песочница в жанре башенная защита.

View File

@@ -1,3 +1,3 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m org.gradle.jvmargs=-Xms256m -Xmx1024m
archash=f1feed86eb643c2e5dbcee013b1b186644b5cf98 archash=e327ec0bf805e7ad3cb4d95b242bf8424c487a64

View File

@@ -58,6 +58,10 @@ public class ServerControl implements ApplicationListener{
private String suggested; private String suggested;
public ServerControl(String[] args){ public ServerControl(String[] args){
setup(args);
}
protected void setup(String[] args){
Core.settings.defaults( Core.settings.defaults(
"bans", "", "bans", "",
"admins", "", "admins", "",
@@ -254,7 +258,7 @@ public class ServerControl implements ApplicationListener{
info("Server loaded. Type @ for help.", "'help'"); info("Server loaded. Type @ for help.", "'help'");
} }
private void registerCommands(){ protected void registerCommands(){
handler.register("help", "Displays this command list.", arg -> { handler.register("help", "Displays this command list.", arg -> {
info("Commands:"); info("Commands:");
for(Command command : handler.getCommandList()){ for(Command command : handler.getCommandList()){
@@ -273,6 +277,7 @@ public class ServerControl implements ApplicationListener{
Core.app.exit(); Core.app.exit();
}); });
handler.register("stop", "Stop hosting the server.", arg -> { handler.register("stop", "Stop hosting the server.", arg -> {
net.closeServer(); net.closeServer();
if(lastTask != null) lastTask.cancel(); if(lastTask != null) lastTask.cancel();

View File

@@ -433,6 +433,15 @@ public class ApplicationTests{
assertEquals(256, world.height()); assertEquals(256, world.height());
} }
@Test
void load114Save(){
resetWorld();
SaveIO.load(Core.files.internal("114.msav"));
assertEquals(500, world.width());
assertEquals(500, world.height());
}
@Test @Test
void arrayIterators(){ void arrayIterators(){
Seq<String> arr = Seq.with("a", "b" , "c", "d", "e", "f"); Seq<String> arr = Seq.with("a", "b" , "c", "d", "e", "f");

Binary file not shown.

View File

@@ -33,7 +33,8 @@ def transformColors = { List<List<String>> list ->
//d4816b //d4816b
transformColors([["a387ea", "8a73c6", "5c5e9f"], ["6e7080", "989aa4", "b0bac0"], ["bc5452", "ea8878", "feb380"], ["de9458", "f8c266", "ffe18f"], ["feb380", "ea8878", "bc5452"], ["d4816b", "eab678", "ffd37f"]]) transformColors([["a387ea", "8a73c6", "5c5e9f"], ["6e7080", "989aa4", "b0bac0"], ["bc5452", "ea8878", "feb380"],
["de9458", "f8c266", "ffe18f"], ["feb380", "ea8878", "bc5452"], ["d4816b", "eab678", "ffd37f"], ["ffffff", "dcc6c6", "9d7f7f"]])
def antialias = { File file -> def antialias = { File file ->
if(!doAntialias) return if(!doAntialias) return