Compare commits

..

194 Commits
v123 ... v125

Author SHA1 Message Date
YellOw139
41b50d67af [Bundle][RO] Update (#4696)
This PR was tested in-game and is ready to merge at any time.

Changelog:

- New strings/changes up to commit 631e4d9eef
- Typo fixes & various other improvements
2021-02-16 13:12:29 -05:00
Vanguard
b65dffca9d 4 new, 1 changed (#4688)
New:
enablebuilding
stat.armor
setting.logichints.name
(newline between radar.output and unitradar.target)

Changed:
lenum.turret
2021-02-16 13:12:17 -05:00
Sharlotte
66bdfcf877 [KO] Update bundles again (#4695)
*translated updated new logic hint
*translated new rule
*typo
2021-02-16 13:12:06 -05:00
Anuken
b0082c92c5 Fixed green line bug - Removed stencil+depth buffers 2021-02-16 13:02:15 -05:00
Anuken
fdd1c01ac3 Merge remote-tracking branch 'origin/master' 2021-02-16 12:20:37 -05:00
Anuken
1ffdd9fd99 Fixed #4701 2021-02-16 12:20:30 -05:00
Patrick 'Quezler' Mounier
f64ad2db9f Remove another dead server (#4699) 2021-02-16 11:46:51 -05:00
Anuken
7bfe9bf914 Merge remote-tracking branch 'origin/master' 2021-02-16 10:57:32 -05:00
Anuken
214f3bb9b5 Improved data file zipping 2021-02-16 10:57:20 -05:00
키에르
3f51149883 Remove dead server (#4669) 2021-02-16 09:50:52 -05:00
Anuken
2c368953f9 Merge remote-tracking branch 'origin/master' 2021-02-16 09:13:49 -05:00
Anuken
9d5454e5ce Fixed #4694 2021-02-16 09:13:44 -05:00
TranquillyUnpleasant
631e4d9eef Unit cap (#4689)
* Add unit caps as a map setting.

* Use int and add maximum and minimum handling.

* Put a lower limit of 0 for unit cap
2021-02-15 20:15:56 -05:00
Anuken
957583071d Splash damage tweaks 2021-02-15 18:42:24 -05:00
Anuken
c942331117 New splash damage algorithm 2021-02-15 18:00:47 -05:00
Anuken
710a55dc2d Reverted pixmap blending rename 2021-02-15 11:08:56 -05:00
Anuken
4bbb4b9a19 Reorder NaN check 2021-02-15 11:00:49 -05:00
彭瑞暄
a2e5dae27f Updated zh-TW translations of Logic Hints (#4666)
* Logic Hint pt.1

Some Logic Hints and minor tweaks in previous translations

* Logic Hints pt.2

* Logic Hints pt. 3/3
2021-02-15 10:46:19 -05:00
YellOw139
d5645b8a7b [Bundle][RO] Update (#4631)
* [Bundle][RO][124.1] Update

This PR was tested in-game and is ready to merge at any time.

Changelog:
- New strings/changes up to commit 64acd6c1e4
- Fixed ancient mod-related bundles not fitting the new install button
- Typo fixes & various other improvements

* Logic tooltips - initial English commit

* Block flags

* Romanian logic hints

* polishing

* Since when is this missing

* Polishing
2021-02-15 10:43:34 -05:00
Sharlotte
a9f9946a39 [KO] TYPO (#4665)
* [KO] i got typo!

* typo
2021-02-15 10:42:28 -05:00
Antsiferov Andrew
561deacce4 [Bundle][RU] Logic Popups L10n (#4677)
* Logic popups

* Block flag documentation

* Распознование -> Распознавание (@Prosta4okua)

* Сбрсывание -> Сбрасывание (@XEN0PHIL)

* нахдиться -> находиться (@XEN0PHIL)

* распознования -> распознавания (@XEN0PHIL)

* распознования -> распознавания (@XEN0PHIL)

* распозновать -> распознавать (@XEN0PHIL)

* распознования -> распознавания (@XEN0PHIL)

* Включен -> Включён (@XEN0PHIL)

* - -> - (@XEN0PHIL)

* lst.unitradar (@XEN0PHIL)

* единиц -> единицы (@XEN0PHIL)
2021-02-15 10:42:01 -05:00
Joshua Fan
e528e35e06 Add sector icon picker back button (#4682) 2021-02-15 10:41:56 -05:00
Anuken
af39d6a6ee Fixed #4685 2021-02-15 10:37:24 -05:00
Patrick 'Quezler' Mounier
7a21c02476 Makes the top sprite visible on liquid turret icons (#4683)
* Add top region to liquid turret icons

* Attempt to change outline icon generation

* Draw regions above the outlined icon over it

* Draw regions **above** the outlined icon over it

* Add clarrifying comment

* Implement backwards compatibility for mods

* an -> any
2021-02-15 09:32:46 -05:00
Patrick 'Quezler' Mounier
557e5710cd Fixes BuilderAI & RepairAI retreat nullpointers (#4681)
* Update BuilderAI.java

* Update RepairAI.java
2021-02-15 09:31:27 -05:00
Anuken
fa52255d04 Fixed #4680 2021-02-15 09:30:57 -05:00
Anuken
e16622afcc Automatic retreat AI for builders/repair units 2021-02-14 20:44:40 -05:00
Anuken
f2468f0b3d Cleanup of #4678 2021-02-14 19:14:02 -05:00
Anuken
30c9231df6 Merge branch 'master' of https://github.com/Anuken/Mindustry 2021-02-14 19:02:55 -05:00
Joshua Fan
7532aadaf8 Add enable building hint, combine building and respawn hints (#4678) 2021-02-14 19:02:28 -05:00
Anuken
3d226246b9 Labyrinth core fix 2021-02-14 09:15:12 -05:00
Skin
d6c852a082 remove-pandorum (#4676)
Good luck!
2021-02-14 08:54:25 -05:00
Anuken
07a27e913c Added UnitBuild transition class 2021-02-14 08:47:53 -05:00
Anuken
092d152bdc Force-link effect classes on iOS 2021-02-13 18:24:22 -05:00
Anuken
8b756d221b Un-broke scripts 2021-02-13 16:28:49 -05:00
Anuken
f33d684dce Merge remote-tracking branch 'origin/master' 2021-02-13 11:56:44 -05:00
Anuken
56e41309b1 Updated global script 2021-02-13 11:56:40 -05:00
RebornTrack970
91b24433b9 Added the 2R2T and Rush server to Omega. (#4667) 2021-02-13 10:37:44 -05:00
Anuken
9050937900 Name cleanup 2021-02-12 19:40:29 -05:00
Anuken
2e6b90d4d5 Serializable -> JsonSerializable 2021-02-12 15:41:28 -05:00
Anuken
146b2589e2 Fixed rare network error 2021-02-12 14:54:10 -05:00
Anuken
abd07e1525 Fixed chat not working while paused 2021-02-12 12:55:31 -05:00
Anuken
541da5c0c9 Block flag documentation & cleanup 2021-02-12 09:09:10 -05:00
Anuken
21f642ad0c Merge remote-tracking branch 'origin/master' 2021-02-12 08:56:44 -05:00
Anuken
0d084d380d Fixed map resize not preserving links 2021-02-12 08:56:40 -05:00
Sharlotte
0fe158d080 [KO] i got typo! (#4662)
* [KO] i got typo!

* typo
2021-02-12 08:42:35 -05:00
Anuken
0cc64c6a8d Fixed #4658 2021-02-12 08:41:36 -05:00
Anuken
cd684996e1 Cleanup & Steam crash fix 2021-02-11 16:31:44 -05:00
Anuken
0350e6bbf4 Validate teams with power links 2021-02-11 12:03:11 -05:00
Anuken
4fe5972d89 Merge remote-tracking branch 'origin/master' 2021-02-11 10:12:17 -05:00
Anuken
27c8efc672 Better targeting range calculation 2021-02-11 10:12:07 -05:00
Catchears
aef0faf79c update german translation to include logic hints (#4654)
* update german bundle to "force projector heat issues"

ea2b57ec4b
ea2b57ec4b

* Gebäude -> Block to prevent confusion
2021-02-11 10:01:03 -05:00
Sharlotte
ea7d1dd91e [KO] UPDATED KO Translation (#4656)
* translated all without logic hint

* typo typo typo typo everywhere typo oh hi typo

* Update logic hint

* typo

* translated changed android description

* android changelog
2021-02-11 09:55:02 -05:00
Anuken
ea2b57ec4b Force projector heat sense 2021-02-10 14:42:30 -05:00
Anuken
949f5eccd7 Damage distance check fix 2021-02-10 09:46:30 -05:00
키에르
e525d89e43 Add missing properties (#4649)
* Add missing properties

* oh no formatting
2021-02-10 09:37:47 -05:00
Patrick 'Quezler' Mounier
6498ce3c4f Remove double indentation of the io server group (#4650) 2021-02-10 09:21:21 -05:00
MEEP of Faith
cbf30c599b If a building and unit are found within the line, target the closer one. (#4646) 2021-02-10 09:16:49 -05:00
Anuken
54c406f83d Cleanup 2021-02-09 18:28:11 -05:00
Anuken
7b2957ab41 More logic tooltips 2021-02-09 15:04:50 -05:00
Anuken
e22fccf5b1 Logic hint tooltips 2021-02-09 14:52:23 -05:00
Anuken
ce8b32f022 Merge remote-tracking branch 'origin/master' 2021-02-09 12:10:22 -05:00
Anuken
0d0aef3dea Logic layout bugfixes 2021-02-09 12:10:15 -05:00
MEEP of Faith
386da22f6e remove space in perShot (#4640) 2021-02-09 09:52:00 -05:00
SachaTending
f76b514892 Update servers_v6.json (#4615)
Add RCR
2021-02-09 09:44:01 -05:00
Anuken
77dc959e4a Merge remote-tracking branch 'origin/master' 2021-02-09 09:35:03 -05:00
Anuken
a99151441c Fixed #4642 / Logic op reorganization 2021-02-09 09:34:58 -05:00
buthed010203
852b0a97fe 60 * 60 > Time.toMinutes (#4634)
It already exists in other places in the code, doesn't make sense to not use it.
2021-02-08 16:49:14 -05:00
Anuken
38843c25fb Merge remote-tracking branch 'origin/master' 2021-02-08 16:44:22 -05:00
Anuken
ce2750ba60 Rail bullet fix 2021-02-08 16:29:41 -05:00
Fatonndev
1d3dbddaef add player.locale (#4633) 2021-02-08 15:26:48 -05:00
Anuken
d8177daada Merge remote-tracking branch 'origin/master' 2021-02-08 14:55:18 -05:00
Anuken
3cbcd779eb Better strict equality implementation 2021-02-08 14:55:14 -05:00
Nexort23
33fc36a2d4 hub minplay.ru (#4600)
* hub minplay.ru
2021-02-08 14:52:11 -05:00
Anuken
c06146110d Better bullet homing (#4630) 2021-02-08 13:03:08 -05:00
Anuken
1802aab683 isNull op / Return null for null block sense/NaNs 2021-02-08 12:48:39 -05:00
Anuken
49fe47f1f8 Comment fix 2021-02-08 12:23:56 -05:00
Anuken
a13c9d0761 Fixed F-Droid build string not updating on deploy 2021-02-08 10:58:05 -05:00
Anuken
3d8479355c Fixed random key 2021-02-08 10:45:08 -05:00
MEEP of Faith
86c702861e Remove NullPointerExeption error (#4624) 2021-02-08 10:44:08 -05:00
CxZxRainzz
47ec13eef4 Update servers_v6.json (#4628)
Add CxZx
2021-02-08 10:39:41 -05:00
Anuken
d8cd0d867c Merge remote-tracking branch 'origin/master' 2021-02-08 10:37:09 -05:00
Anuken
d5ede6b1bb Un-blacklisted arc.net 2021-02-08 10:37:06 -05:00
키에르
fd931564aa Add sources jar (#4612)
* Add sources jar

* Update build.gradle

* Fix classes not found

* :core

* formatting

Co-authored-by: Anuken <arnukren@gmail.com>
2021-02-08 09:59:11 -05:00
Anuken
6b19178a13 Fixed #4620 2021-02-08 09:52:41 -05:00
Anuken
64acd6c1e4 Merge remote-tracking branch 'origin/master' 2021-02-08 09:42:57 -05:00
Anuken
560914bebe Added more unit stats to database 2021-02-08 09:42:49 -05:00
Anuken
2edec90dfb Cleanup 2021-02-08 09:25:46 -05:00
Catchears
10c1305eae update german translation for build 124 (#4618)
* update german translation for build 124

* shorten text to fit on the button without newline
2021-02-07 17:16:56 -05:00
Joshua Fan
852c98f004 "[E] to enable building" hint while building is paused (#3857)
* Show building hints while building is paused

* Add hint: [E] to enable building

* Remove .left()

* Fix build enable hint display inconsistencies when changing build auto-pause setting

* Combine building hint tables

* Fix indentation
2021-02-07 16:58:42 -05:00
Patrick 'Quezler' Mounier
292f771eb1 Draws team regions during schematic placement (#4588)
* Draw team regions during schematic placement

* Fall back to sharded for headless

* Only draw team regions if the schematic is in-world

This seems better than `player != null && req.worldContext` since it wouldn't really result in any visual changes but saves some draw operations.

* This seems cleaner

Although the order of the 1st and 2nd if argument is debatable for performance reasons.
2021-02-07 13:27:09 -05:00
Anuken
1acc771edc 'Fixed' some iOS warnings 2021-02-07 13:08:10 -05:00
Anuken
ee61d0dcfa Cleanup 2021-02-07 13:01:30 -05:00
Anuken
e5f2073de2 Minor unit balance tweaks 2021-02-07 12:49:26 -05:00
Anuken
816be9e9bd Force projector visual cleanup 2021-02-07 12:38:24 -05:00
Sunny Kim
2107af1f0f Force projection disappearing visuals (#4504)
* forceShrink

* forceShrink

* more quicker to tell it apart from a shield down
2021-02-07 12:36:29 -05:00
MEEP of Faith
3bb85b4bda Custom shadow offset (#4472) 2021-02-07 12:34:54 -05:00
YellOw139
e86a3e9d09 [Bundle][RO][Ready-for-Stable] Translation & metadata update + minor fix (#4409)
* #3958 hotfix

* update Romanian Steam desc count

* Create title.txt

* Add files via upload

* Sorter gates

* charge

* Polishing

* More mod browser
2021-02-07 12:33:51 -05:00
Szczepan Zalega
957426c27f Fix some typos in Polish translation (#4411)
* Fix some typos in Polish translation

* Update bundle_pl.properties

(fixup)
2021-02-07 12:33:45 -05:00
Vanguard
8bc90a19d2 [bundle] update bundle_ru.properties (#4477)
* 1 line changed

- noname

* 1 line changed

- hint.placeTurret

* 3 new lines

- servers.disclaimer
- hint.coreUpgrade
- hint.presetLaunch

----
NOTE from Felix Corvus (@Remint32)

This commit and PR are the last ones I made to the repository.
I want to sincerely thank the people I worked with to enhance the game and translate it into Russian.

I want to thank you separately:
Prosta4ok_ua (@Prosta4okua), Vanguard (@XEN0PHIL), BasedUser (@BasedUser), Summet (@summetdev), Anuke (@Anuken), The_Slaylord (@TheSlaylord), Lonely_Ymomfe (@ymomfe), and XZimur (@XZimur)

* 5 changed lines; 2 new lines

Changed:
globalitems
sector.extractionOutpost.description
hint.launch
hint.launch.mobile
hint.presetLaunch

New:
hint.coreIncinerate
hint.coopCampaign

* 2 changed line

hint.coopCampaign
item.spore-pod.details
-
В споровом стручке всё же множественное число в описании, говорится про сами споры. THEY EMIT - они выделяют, IT EMITS - он выделяет.

* 2 changed lines

hint.coreIncinerate
block.interplanetary-accelerator.description

* 3 new line; 1 changed line

New:
setting.showweather.name
link.bug.description
rules.weather.always

Changed:
keybinds.mobile

* 4 new lines; 1 changed line; 1 deleted line

New:
public.confirm.really
bullet.buildingdamage
stat.ammouse
unit.pershot

Changed:
bullet.knockback

Deleted:
bar.limitreached

* Update bundle_ru.properties

падежи

* Update bundle_ru.properties

мелочи

* 1 changed line

stat.ammouse

* 1 new line

none.found

* 6 changed; 1 deleted

Changed:
mod.featured.dialog.title
mods.browser.add
mods.github.open
mod.import.github
mod.jarwarn
mods.guide

Deleted:
mod.featured.title

* 2 changed lines

link.bug.description
mod.scripts.disable

* Update achievements.vdf

* Update description.txt

* 1 changed line

item.thorium.description

* 1 new line

rules.coreincinerates

* 1 new line

bar.boost

* 1 new line

max

* Update bundle_ru.properties

* Update bundle_ru.properties

* rip v3.5 maps

* Update bundle_ru.properties

* Update bundle_ru.properties

* Update bundle_ru.properties

* Prosta4ok obnovi repository

* взлЁт

* 3 new lines

mods.browser.sortdate
mods.browser.sortstars
stat.charge

* Update description.txt

* Update description.txt

* 3 changed, 3 new, 1 deleted

Changed:
mods.browser.sortdate
unit.sei.description
unit.risso.description

New:
mods.browser.reinstall
mods.viewcontent
mods.browser

Deleted:
mod.featured.dialog.title

* 1 line changed

mods.github.open
-
"Репо" is not commonly used and "Репозиторий" does not fit in the button

* 1 new line

mod.installed

Co-authored-by: Felix Corvus <remint32@yandex.ru>
Co-authored-by: Prosta4okua <31485341+Prosta4okua@users.noreply.github.com>
Co-authored-by: Antsiferov Andrew <summet.dev@gmail.com>
2021-02-07 12:33:18 -05:00
Prosta4okua
668144cf2a [Bundle]Update bundle_uk_UA.properties (#4434)
* Update bundle_uk_UA.properties

* Update bundle_uk_UA.properties
2021-02-07 12:32:57 -05:00
Anuken
c5ed056601 Removed unused fx 2021-02-07 12:12:15 -05:00
Anuken
ea9d415b92 iOS inset rotation fix 2021-02-07 11:43:34 -05:00
Anuken
c181204700 Fixed mod descriptions going off-screen 2021-02-07 10:44:45 -05:00
Anuken
ca78cb1a3f Fixed #4616 2021-02-07 10:21:38 -05:00
Anuken
fdafa0933f Mod browser layout tweaks 2021-02-07 10:04:46 -05:00
Anuken
ae92813169 Merge remote-tracking branch 'origin/master' 2021-02-07 09:50:37 -05:00
Anuken
8a248dc787 Mod browser layout fixes 2021-02-07 09:50:33 -05:00
Leonid Skorospelov
f90f611a6d plastanium-wall-large schematicPriority should also be 10 (#4613)
plastanium-wall has it, makes sense to put for large one as well
2021-02-07 09:14:19 -05:00
Xasmedy
1c0d148607 Removed same if statement. (#4607)
Removed an if statement that was the same of the one up.
2021-02-06 18:13:48 -05:00
Anuken
95c8b7ae60 Merge branch 'master' of https://github.com/Anuken/Mindustry 2021-02-06 12:06:03 -05:00
Anuken
25d013b768 Mod browser icon support 2021-02-06 12:05:59 -05:00
Patrick 'Quezler' Mounier
9de8c4d8ac Update servers_be.json (#4602) 2021-02-06 09:09:56 -05:00
Anuken
7e4ffe6a7d Fixed builds failing without Android project 2021-02-06 08:43:15 -05:00
Anuken
b90372a226 Testing bloom on iOS 2021-02-06 08:37:02 -05:00
Anuken
9adbfcac0f Re-added jcenter repo 2021-02-05 14:11:52 -05:00
Anuken
d1eb7743ad Better mod browser horizontal layout 2021-02-05 12:12:08 -05:00
Anuken
fc3352bcb1 Java mod import support / Moved mod browser button 2021-02-05 11:21:27 -05:00
Anuken
9b3360d932 Mod content lists 2021-02-04 21:02:57 -05:00
Anuken
3784bfac77 Allow mod re-import / Save mod repo on import 2021-02-04 19:30:52 -05:00
Anuken
54754cd177 Don't reset processors when links change 2021-02-04 18:19:56 -05:00
Anuken
c48034e420 Merge remote-tracking branch 'origin/master' 2021-02-04 14:12:07 -05:00
Anuken
3299279c89 Removed jcenter repositories 2021-02-04 14:12:03 -05:00
Patrick 'Quezler' Mounier
a6c3ebc467 Save rotation of repair points (#4586) 2021-02-04 10:23:17 -05:00
Anuken
9f510f61c7 Fixed #4584 2021-02-04 09:25:52 -05:00
Anuken
3ae48b8753 Merge remote-tracking branch 'origin/master' 2021-02-03 19:17:14 -05:00
Anuken
f41725b8dc Minimap unit rendering fix 2021-02-03 19:17:07 -05:00
Fatonndev
115df3aedd Add obvilionnetwork.ru Recapture and Attack servers (#4582)
* Add obvilionnetwork.ru Recapture and Attack servers

* Update servers_v6.json

* Update servers_v6.json
2021-02-03 17:04:55 -05:00
buthed010203
3c136ad0ba add transportation group to container and vault (#4499)
this allows for them to be placed over belts so that people no longer have to clear an area around the core when placing vaults around it.
2021-02-02 15:32:52 -05:00
Patrick 'Quezler' Mounier
48ee3d255d Make timescale accessible to logic (#4503) 2021-02-02 15:20:36 -05:00
QmelZ
b05f867800 add rotation to ParticleEffect (#4501)
* add rotation to ParticleEffect

* add offset
2021-02-02 13:14:47 -05:00
Anuken
55b790a0d4 Merge remote-tracking branch 'origin/master' 2021-02-02 13:13:45 -05:00
Anuken
57f6c9dfd9 Mech rebalancing 2021-02-02 13:13:38 -05:00
Nikopol
2f9c95afd0 Moving server to C.A.M.S. (#4497)
NikoCHIO now in C.A.M.S.
2021-02-02 09:22:54 -05:00
彭瑞暄
4fe1457d96 Updated zh-TW translations (#4449)
* Update bundle_zh_TW.properties

mod sorting & charge

* Changed "Charge"

A better translation came to mind
2021-02-01 09:29:03 -05:00
Folker
2589a27cb5 Create FileTreeInitEvent (#4489)
* filetree init event

* actions do your thing
2021-02-01 09:27:24 -05:00
Anuken
8704e14fd7 Fixed #4493 / Fixed #4492 / Fixed #4490 2021-02-01 09:24:39 -05:00
Anuken
2b17dbe390 #4487 but properly implemented 2021-01-31 19:44:29 -05:00
Anuken
919012608a Merge remote-tracking branch 'origin/master' 2021-01-31 16:35:17 -05:00
Anuken
5675a5b035 F 2021-01-31 16:35:13 -05:00
RebornTrack970
6724752980 Added server Omega (#4435)
* Added server Omega

This is the hub of my servers. The other ip for it is: omega.my.to:25906 but that one sometimes doesnt work.

* changed the ip to dns version

* the ip seems more useable

some devices cant seem to connet to dns.

Co-authored-by: Anuken <arnukren@gmail.com>
2021-01-31 15:58:26 -05:00
UnCaughT
0e078a9c60 Update servers_v6.json (#4452)
Русскоязычный сервер с Hex сражениями.
2021-01-31 15:57:08 -05:00
_owler_#0954
c0b1dfc55a closed. (#4481) 2021-01-31 15:52:55 -05:00
Anuken
3d201f7042 Fixed #4474 / Fixed #4475 / Fixed #4476 / Fixed #4483 2021-01-31 15:51:42 -05:00
Anuken
f1a5aae30a Merge remote-tracking branch 'origin/master' 2021-01-29 12:02:36 -05:00
Anuken
9142da2b70 Stop shooting upon crawler death 2021-01-29 12:02:31 -05:00
Vajda Simon
022c76bf45 bundle_hu.properties (#4464)
They spoke on Discord because of an incorrect translation.
2021-01-29 09:40:07 -05:00
Patrick 'Quezler' Mounier
bc6db72df0 Make fillitems fill the core to the brim (#4462)
Instead of just setting all items to the capacity of the first found core.
2021-01-29 09:38:26 -05:00
Anuken
d512aa5b21 Fixed #4463 2021-01-29 09:32:29 -05:00
Anuken
7cdf7a21fe Minor power graph optimizations 2021-01-28 12:07:50 -05:00
Anuken
9a5a6e1ce2 Merge remote-tracking branch 'origin/master' 2021-01-28 10:23:07 -05:00
Anuken
5a258d2830 Fixed #4461 2021-01-28 10:23:02 -05:00
Patrick 'Quezler' Mounier
96ee32f8ed Custom Game Underline 2: Electric Boogaloo (#4457)
* Update CustomGameDialog.java

* Remove .row() for consistensy
2021-01-28 09:06:30 -05:00
Joshua Fan
a667a94c8e Draw plastanium conveyors on conveyors layer (#4446) 2021-01-27 12:08:51 -05:00
Anuken
d0572a2a0d Merge remote-tracking branch 'origin/master' 2021-01-27 11:49:08 -05:00
Anuken
47eea79b60 Fixed #4453 / Fixed #4450 2021-01-27 11:49:04 -05:00
Patrick 'Quezler' Mounier
03b37235b3 producer -> generator (#4441) 2021-01-26 11:35:48 -05:00
Patrick 'Quezler' Mounier
6969fbb1e7 Give tsunami the extinguisher flag as well (#4442) 2021-01-26 11:31:36 -05:00
Anuken
ccc59aa61b Minor wave task tweaks 2021-01-26 10:37:36 -05:00
Anuken
c658865907 Dynamic lightning damage tweaks 2021-01-25 17:21:12 -05:00
Sunny Kim
a13d51e09a Charge stat for Item (#4392)
* Stat.discharge, discharge

* Update Items.java

* item.discharge

* full container = somewhat more than 4 full batteries

* Stat.discharge

* stat.discharge = Discharge

* Update core/src/mindustry/type/Item.java

Co-authored-by: Antsiferov Andrew <summet.dev@gmail.com>

* removed dis

* oops

* unit zap

Co-authored-by: Antsiferov Andrew <summet.dev@gmail.com>
2021-01-25 17:10:34 -05:00
Anuken
f827337259 Merge remote-tracking branch 'origin/master' 2021-01-25 16:16:45 -05:00
Anuken
b83c76f728 Improved liquid bridge throughput 2021-01-25 16:16:38 -05:00
Thomas Widyantoko
5666fd4999 new update in_ID translation (#4437)
yes
2021-01-25 14:32:35 -05:00
Anuken
5930e3c350 Cleanup 2021-01-25 12:53:27 -05:00
Anuken
4630e5b3a4 Wave spawning improvements 2021-01-25 10:28:36 -05:00
Anuken
f16990edcb Reconstructors: Accept unit dropped payload when disabled 2021-01-24 20:20:03 -05:00
FrederickDoering
13896589c2 Made disabling payload conveyors output from routers more reliable. (#4433)
Prevented reconstructors from being roughted to when disabled.

Co-authored-by: frederick_efd <frederick.doering@nordson.com>
2021-01-24 20:18:09 -05:00
Anuken
8b5cf5309a Reactive effect flag 2021-01-24 15:22:41 -05:00
Anuken
baedba0d5b Mutual status effect transitions 2021-01-24 14:20:48 -05:00
Anuken
9f926ef71e Merge remote-tracking branch 'origin/master' 2021-01-24 13:08:05 -05:00
Anuken
18a3f8bb68 Fixed #4431 2021-01-24 13:08:01 -05:00
genNAowl
623b7ada11 Let Logic Sense Range (#4425)
Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com>
2021-01-24 09:23:12 -05:00
_owler_#0954
6b6d52e2fd Add new minigame (#4427)
PvP version of tower defence
2021-01-24 09:22:44 -05:00
MEEP of Faith
fc91b6b135 Colored construct (#4417) 2021-01-23 15:29:36 -05:00
Anuken
f9c33453f2 Merge remote-tracking branch 'origin/master' 2021-01-23 10:33:10 -05:00
Anuken
ad4650f408 Fixed #4420 / Fixed #4418 / Fixed #4416 2021-01-23 10:33:06 -05:00
Joshua Fan
8ca08a0f14 Make schematics build insulated blocks first, power nodes last (#4414)
* Make schematics build insulated blocks first, power nodes last

* Add schematicPriority property to sort by

* Assign schematicPriority of 10 to power diode
2021-01-23 10:28:26 -05:00
Anuken
792fdef95d Minor parse fix 2021-01-21 21:25:04 -05:00
Anuken
457514a2c8 Fixed #4407 2021-01-21 21:21:02 -05:00
Anuken
027d080c55 Fixed #4403 2021-01-21 16:10:16 -05:00
Anuken
bf8f059c25 Merge remote-tracking branch 'origin/master' 2021-01-21 14:45:51 -05:00
Anuken
a73165353f Fixed #4402 2021-01-21 14:45:43 -05:00
Nikopol
613b5a7703 Update servers_v6.json (#4401) 2021-01-21 10:54:24 -05:00
genNAowl
988791f18d Let Logic set (and read) Illuminator Color (#4374)
* illluminator color logic control

* remove sense

Co-authored-by: Leonwang4234 <62972692+Leonwang4234@users.noreply.github.com>
2021-01-21 09:30:36 -05:00
Patrick 'Quezler' Mounier
1fb608220f Make impact reactor warmup sensable as heat (#4399)
* Make impact reactor warmup sensable as heat

* Update ImpactReactor.java
2021-01-21 09:30:25 -05:00
키에르
56b87a2141 Add kr server (#4378)
* Add kr server

* Update servers_v6.json

Co-authored-by: Blockzilla101 <48705529+Blockzilla101@users.noreply.github.com>

Co-authored-by: Blockzilla101 <48705529+Blockzilla101@users.noreply.github.com>
2021-01-21 09:13:07 -05:00
Anuken
3aee9bddd4 Cleanup 2021-01-21 08:54:14 -05:00
Sunny Kim
65f97edbc5 Add search option for mod browser (#4391)
* add search option

* mods.browser.sortdate

* mods.browser

* Update bundle_ko.properties

* oopsie

* clearPartiali

* half of my brain cells failed to boot
2021-01-21 08:51:43 -05:00
Anuken
d393230add . 2021-01-21 08:50:25 -05:00
Anuken
75d2b0fb69 Fixed #4393 / Fixed #4398 2021-01-21 08:48:36 -05:00
Anuken
0cc9b0b0a3 Mod version parse fix 2021-01-20 16:44:04 -05:00
Anuken
9b6c125233 UI.formatAmount for negative numbers 2021-01-20 16:38:46 -05:00
Anuken
1f2b331bf6 Possible Android mod extension fix 2021-01-20 14:48:54 -05:00
174 changed files with 2967 additions and 1030 deletions

View File

@@ -17,21 +17,6 @@ jobs:
java-version: 14 java-version: 14
- name: Set env - name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Create artifacts
run: |
./gradlew desktop:dist server:dist core:javadoc -Pbuildversion=${RELEASE_VERSION:1}
- name: Update docs
run: |
cd ../
git config --global user.email "cli@github.com"
git config --global user.name "Github Actions"
git clone --depth=1 https://github.com/MindustryGame/docs.git
cp -a Mindustry/core/build/docs/javadoc/. docs/
cd docs
git add .
git commit -m "Update ${RELEASE_VERSION:1}"
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/MindustryGame/docs
cd ../Mindustry
- name: Add Arc release - name: Add Arc release
run: | run: |
git clone --depth=1 --branch=master https://github.com/Anuken/Arc ../Arc git clone --depth=1 --branch=master https://github.com/Anuken/Arc ../Arc
@@ -39,6 +24,24 @@ jobs:
git tag ${RELEASE_VERSION} git tag ${RELEASE_VERSION}
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/Arc ${RELEASE_VERSION}; git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/Arc ${RELEASE_VERSION};
cd ../Mindustry cd ../Mindustry
- name: Create artifacts
run: |
./gradlew desktop:dist server:dist core:mergedJavadoc -Pbuildversion=${RELEASE_VERSION:1}
- name: Update docs
run: |
cd ../
git config --global user.email "cli@github.com"
git config --global user.name "Github Actions"
git clone --depth=1 https://github.com/MindustryGame/docs.git
cd docs
find . -maxdepth 1 ! -name ".git" ! -name . -exec rm -r {} \;
cd ../
cp -a Mindustry/core/build/javadoc/. docs/
cd docs
git add .
git commit -m "Update ${RELEASE_VERSION:1}"
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/MindustryGame/docs
cd ../Mindustry
- name: Update F-Droid build string - name: Update F-Droid build string
run: | run: |
git clone --depth=1 --branch=master https://github.com/Anuken/MindustryBuilds ../MindustryBuilds git clone --depth=1 --branch=master https://github.com/Anuken/MindustryBuilds ../MindustryBuilds
@@ -47,6 +50,7 @@ jobs:
echo versionName=6-fdroid-${RELEASE_VERSION:1}$'\n'versionCode=${RELEASE_VERSION:1} > version_fdroid.txt echo versionName=6-fdroid-${RELEASE_VERSION:1}$'\n'versionCode=${RELEASE_VERSION:1} > version_fdroid.txt
git add . git add .
git commit -m "Updating to build ${RELEASE_VERSION:1}" git commit -m "Updating to build ${RELEASE_VERSION:1}"
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/Anuken/MindustryBuilds
cd ../Mindustry cd ../Mindustry
- name: Upload client artifacts - name: Upload client artifacts
uses: svenstaro/upload-release-action@v2 uses: svenstaro/upload-release-action@v2

1
.gitignore vendored
View File

@@ -43,6 +43,7 @@ ios/robovm.properties
packr-out/ packr-out/
config/ config/
*.gif *.gif
/tests/out
/core/assets/basepartnames /core/assets/basepartnames
version.properties version.properties

View File

@@ -4,7 +4,6 @@ buildscript{
mavenCentral() mavenCentral()
google() google()
maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" } maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
} }
dependencies{ dependencies{
@@ -20,8 +19,8 @@ configurations{ natives }
repositories{ repositories{
mavenCentral() mavenCentral()
jcenter()
maven{ url "https://maven.google.com" } maven{ url "https://maven.google.com" }
jcenter() //remove later once google fixes the dependency
} }
dependencies{ dependencies{

View File

@@ -162,7 +162,6 @@ public class AndroidLauncher extends AndroidApplication{
}, new AndroidApplicationConfiguration(){{ }, new AndroidApplicationConfiguration(){{
useImmersiveMode = true; useImmersiveMode = true;
hideStatusBar = true; hideStatusBar = true;
stencil = 8;
}}); }});
checkFiles(getIntent()); checkFiles(getIntent());

View File

@@ -12,7 +12,6 @@ buildscript{
mavenCentral() mavenCentral()
google() google()
maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" } maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
maven{ url 'https://jitpack.io' } maven{ url 'https://jitpack.io' }
} }
@@ -184,7 +183,6 @@ allprojects{
maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" } maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven{ url "https://oss.sonatype.org/content/repositories/releases/" } maven{ url "https://oss.sonatype.org/content/repositories/releases/" }
maven{ url 'https://jitpack.io' } maven{ url 'https://jitpack.io' }
jcenter()
} }
task clearCache{ task clearCache{
@@ -320,6 +318,15 @@ project(":core"){
} }
} }
task sourcesJar(type: Jar, dependsOn: classes){
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts{
archives sourcesJar
}
dependencies{ dependencies{
compileJava.dependsOn(preGen) compileJava.dependsOn(preGen)
@@ -337,6 +344,28 @@ project(":core"){
annotationProcessor 'com.github.Anuken:jabel:34e4c172e65b3928cd9eabe1993654ea79c409cd' annotationProcessor 'com.github.Anuken:jabel:34e4c172e65b3928cd9eabe1993654ea79c409cd'
} }
afterEvaluate{
task mergedJavadoc(type: Javadoc){
def blacklist = [project(":ios"), project(":desktop"), project(":server"), project(":annotations")]
if(findProject(":android") != null){
blacklist += project(":android")
}
source rootProject.subprojects.collect{ project ->
if(!blacklist.contains(project) && project.hasProperty("sourceSets")){
return project.sourceSets.main.allJava
}
}
classpath = files(rootProject.subprojects.collect { project ->
if(!blacklist.contains(project) && project.hasProperty("sourceSets")){
return project.sourceSets.main.compileClasspath
}
})
destinationDir = new File(buildDir, 'javadoc')
}
}
} }
project(":server"){ project(":server"){

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -41,10 +41,13 @@ be.ignore = Ignore
be.noupdates = No updates found. be.noupdates = No updates found.
be.check = Check for updates be.check = Check for updates
mod.featured.dialog.title = Mod Browser (WIP) mods.browser = Mod Browser
mods.browser.selected = Selected mod mods.browser.selected = Selected mod
mods.browser.add = Install mods.browser.add = Install
mods.github.open = View mods.browser.reinstall = Reinstall
mods.github.open = Repo
mods.browser.sortdate = Sort by recent
mods.browser.sortstars = Sort by stars
schematic = Schematic schematic = Schematic
schematic.add = Save Schematic... schematic.add = Save Schematic...
@@ -116,8 +119,10 @@ mods.none = [lightgray]No mods found!
mods.guide = Modding Guide mods.guide = Modding Guide
mods.report = Report Bug mods.report = Report Bug
mods.openfolder = Open Folder mods.openfolder = Open Folder
mods.viewcontent = View Content
mods.reload = Reload mods.reload = Reload
mods.reloadexit = The game will now exit, to reload mods. mods.reloadexit = The game will now exit, to reload mods.
mod.installed = [[Installed]
mod.display = [gray]Mod:[orange] {0} mod.display = [gray]Mod:[orange] {0}
mod.enabled = [lightgray]Enabled mod.enabled = [lightgray]Enabled
mod.disabled = [scarlet]Disabled mod.disabled = [scarlet]Disabled
@@ -307,6 +312,7 @@ cancelbuilding = [accent][[{0}][] to clear plan
selectschematic = [accent][[{0}][] to select+copy selectschematic = [accent][[{0}][] to select+copy
pausebuilding = [accent][[{0}][] to pause building pausebuilding = [accent][[{0}][] to pause building
resumebuilding = [scarlet][[{0}][] to resume building resumebuilding = [scarlet][[{0}][] to resume building
enablebuilding = [scarlet][[{0}][] to enable building
showui = UI hidden.\nPress [accent][[{0}][] to show UI. showui = UI hidden.\nPress [accent][[{0}][] to show UI.
wave = [accent]Wave {0} wave = [accent]Wave {0}
wave.cap = [accent]Wave {0}/{1} wave.cap = [accent]Wave {0}/{1}
@@ -678,6 +684,7 @@ stat.drillspeed = Base Drill Speed
stat.boosteffect = Boost Effect stat.boosteffect = Boost Effect
stat.maxunits = Max Active Units stat.maxunits = Max Active Units
stat.health = Health stat.health = Health
stat.armor = Armor
stat.buildtime = Build Time stat.buildtime = Build Time
stat.maxconsecutive = Max Consecutive stat.maxconsecutive = Max Consecutive
stat.buildcost = Build Cost stat.buildcost = Build Cost
@@ -693,6 +700,7 @@ stat.lightningchance = Lightning Chance
stat.lightningdamage = Lightning Damage stat.lightningdamage = Lightning Damage
stat.flammability = Flammability stat.flammability = Flammability
stat.radioactivity = Radioactivity stat.radioactivity = Radioactivity
stat.charge = Charge
stat.heatcapacity = Heat Capacity stat.heatcapacity = Heat Capacity
stat.viscosity = Viscosity stat.viscosity = Viscosity
stat.temperature = Temperature stat.temperature = Temperature
@@ -788,6 +796,7 @@ setting.shadows.name = Shadows
setting.blockreplace.name = Automatic Block Suggestions setting.blockreplace.name = Automatic Block Suggestions
setting.linear.name = Linear Filtering setting.linear.name = Linear Filtering
setting.hints.name = Hints setting.hints.name = Hints
setting.logichints.name = Logic Hints
setting.flow.name = Display Resource Flow Rate setting.flow.name = Display Resource Flow Rate
setting.backgroundpause.name = Pause In Background setting.backgroundpause.name = Pause In Background
setting.buildautopause.name = Auto-Pause Building setting.buildautopause.name = Auto-Pause Building
@@ -948,6 +957,8 @@ rules.blockdamagemultiplier = Block Damage Multiplier
rules.unitbuildspeedmultiplier = Unit Production Speed Multiplier rules.unitbuildspeedmultiplier = Unit Production Speed Multiplier
rules.unithealthmultiplier = Unit Health Multiplier rules.unithealthmultiplier = Unit Health Multiplier
rules.unitdamagemultiplier = Unit Damage Multiplier rules.unitdamagemultiplier = Unit Damage Multiplier
rules.unitcapvariable = Cores Contribute To Unit Cap
rules.unitcap = Base Unit Cap
rules.enemycorebuildradius = Enemy Core No-Build Radius:[lightgray] (tiles) rules.enemycorebuildradius = Enemy Core No-Build Radius:[lightgray] (tiles)
rules.wavespacing = Wave Spacing:[lightgray] (sec) rules.wavespacing = Wave Spacing:[lightgray] (sec)
rules.buildcostmultiplier = Build Cost Multiplier rules.buildcostmultiplier = Build Cost Multiplier
@@ -1505,3 +1516,127 @@ unit.omura.description = Fires a long-range piercing railgun bolt at enemies. Co
unit.alpha.description = Defends the Shard core from enemies. Builds structures. unit.alpha.description = Defends the Shard core from enemies. Builds structures.
unit.beta.description = Defends the Foundation core from enemies. Builds structures. unit.beta.description = Defends the Foundation core from enemies. Builds structures.
unit.gamma.description = Defends the Nucleus core from enemies. Builds structures. unit.gamma.description = Defends the Nucleus core from enemies. Builds structures.
lst.read = Read a number from a linked memory cell.
lst.write = Write a number to a linked memory cell.
lst.print = Add text to the print buffer.\nDoes not display anything until [accent]Print Flush[] is used.
lst.draw = Add an operation to the drawing buffer.\nDoes not display anything until [accent]Draw Flush[] is used.
lst.drawflush = Flush queued [accent]Draw[] operations to a display.
lst.printflush = Flush queued [accent]Print[] operations to a message block.
lst.getlink = Get a processor link by index. Starts at 0.
lst.control = Control a building.
lst.radar = Locate units around a building with range.
lst.sensor = Get data from a building or unit.
lst.set = Set a variable.
lst.operation = Perform an operation on 1-2 variables.
lst.end = Jump to the top of the instruction stack.
lst.jump = Conditionally jump to another statement.
lst.unitbind = Bind to the next unit of a type, and store it in [accent]@unit[].
lst.unitcontrol = Control the currently bound unit.
lst.unitradar = Locate units around the currently bound unit.
lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit.
lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string.
lenum.shoot = Shoot at a position.
lenum.shootp = Shoot at a unit/building with velocity prediction.
lenum.configure = Building configuration, e.g. sorter item.
lenum.enabled = Whether the block is enabled.
lenum.color = Illuminator color.
lenum.always = Always true.
lenum.idiv = Integer division.
lenum.div = Division.\nReturns [accent]null[] on divide-by-zero.
lenum.mod = Modulo.
lenum.equal = Equal. Coerces types.\nNon-null objects compared with numbers become 1, otherwise 0.
lenum.notequal = Not equal. Coerces types.
lenum.strictequal = Strict equality. Does not coerce types.\nCan be used to check for [accent]null[].
lenum.shl = Bit-shift left.
lenum.shr = Bit-shift right.
lenum.or = Bitwise OR.
lenum.land = Logical AND.
lenum.and = Bitwise AND.
lenum.not = Bitwise flip.
lenum.xor = Bitwise XOR.
lenum.min = Minimum of two numbers.
lenum.max = Maximum of two numbers.
lenum.angle = Angle of vector in degrees.
lenum.len = Length of vector.
lenum.sin = Sine, in degrees.
lenum.cos = Cosine, in degrees.
lenum.tan = Tangent, in degrees.
#not a typo, look up 'range notation'
lenum.rand = Random number in range [0, value).
lenum.log = Natural logarithm (ln).
lenum.log10 = Base 10 logarithm.
lenum.noise = 2D simplex noise.
lenum.abs = Absolute value.
lenum.sqrt = Square root.
lenum.any = Any unit.
lenum.ally = Ally unit.
lenum.attacker = Unit with a weapon.
lenum.enemy = Enemy unit.
lenum.boss = Guardian unit.
lenum.flying = Flying unit.
lenum.ground = Ground unit.
lenum.player = Unit controlled by a player.
lenum.ore = Ore deposit.
lenum.damaged = Damaged ally building.
lenum.spawn = Enemy spawn point.\nMay be a core or a position.
lenum.building = Building in a specific group.
lenum.core = Any core.
lenum.storage = Storage building, e.g. Vault.
lenum.generator = Buildings that generate power.
lenum.factory = Buildings that transform resources.
lenum.repair = Repair points.
lenum.rally = Command center.
lenum.battery = Any battery.
lenum.resupply = Resupply points.\nOnly relevant when [accent]"Unit Ammo"[] is enabled.
lenum.reactor = Impact/Thorium reactor.
lenum.turret = Any turret.
sensor.in = The building/unit to sense.
radar.from = Building to sense from.\nSensor range is limited by building range.
radar.target = Filter for units to sense.
radar.and = Additional filters.
radar.order = Sorting order. 0 to reverse.
radar.sort = Metric to sort results by.
radar.output = Variable to write output unit to.
unitradar.target = Filter for units to sense.
unitradar.and = Additional filters.
unitradar.order = Sorting order. 0 to reverse.
unitradar.sort = Metric to sort results by.
unitradar.output = Variable to write output unit to.
control.of = Building to control.
control.unit = Unit/building to aim at.
control.shoot = Whether to shoot.
unitlocate.enemy = Whether to locate enemy buildings.
unitlocate.found = Whether the object was found.
unitlocate.building = Output variable for located building.
unitlocate.outx = Output X coordinate.
unitlocate.outy = Output Y coordinate.
unitlocate.group = Building group to look for.
lenum.stop = Stop moving/mining/building.
lenum.move = Move to exact position.
lenum.approach = Approach a position with a radius.
lenum.pathfind = Pathfind to the enemy spawn.
lenum.target = Shoot a position.
lenum.targetp = Shoot a target with velocity prediction.
lenum.itemdrop = Drop an item.
lenum.itemtake = Take an item from a building.
lenum.paydrop = Drop current payload.
lenum.paytake = Pick up payload at current location.
lenum.flag = Numeric unit flag.
lenum.mine = Mine at a position.
lenum.build = Build a structure.
lenum.getblock = Fetch a building and type at coordinates.\nUnit must be in range of position.\nSolid non-buildings will have the type [accent]@solid[].
lenum.within = Check if unit is near a position.
lenum.boost = Start/stop boosting.

View File

@@ -41,10 +41,13 @@ be.ignore = Ignorieren
be.noupdates = Keine Aktualisierungen gefunden. be.noupdates = Keine Aktualisierungen gefunden.
be.check = Auf Aktualisierungen prüfen be.check = Auf Aktualisierungen prüfen
mod.featured.dialog.title = Mod Browser (unfertig) mod.featured.dialog.title = Mod Browser
mods.browser.selected = Ausgewählter Mod mods.browser.selected = Ausgewählter Mod
mods.browser.add = Installieren mods.browser.add = Installieren
mods.github.open = Ansehen mods.browser.reinstall = Neu Installieren
mods.github.open = Github
mods.browser.sortdate = Nach neusten sortieren
mods.browser.sortstars = Nach Sternen sortieren
schematic = Entwurf schematic = Entwurf
schematic.add = Entwurf speichern... schematic.add = Entwurf speichern...
@@ -68,9 +71,9 @@ schematic.disabled = [scarlet]Entwürfe deaktiviert[]\nAuf dieser [accent]Karte[
stats = Statistiken stats = Statistiken
stat.wave = Wellen besiegt:[accent] {0} stat.wave = Wellen besiegt:[accent] {0}
stat.enemiesDestroyed = Gegner zerstört:[accent] {0} stat.enemiesDestroyed = Gegner zerstört:[accent] {0}
stat.built = Gebäude gebaut:[accent] {0} stat.built = Blöcke gebaut:[accent] {0}
stat.destroyed = Gebäude zerstört:[accent] {0} stat.destroyed = Blöcke zerstört:[accent] {0}
stat.deconstructed = Gebäude abgebaut:[accent] {0} stat.deconstructed = Blöcke abgebaut:[accent] {0}
stat.delivered = Übertragene Ressourcen: stat.delivered = Übertragene Ressourcen:
stat.playtime = Spielzeit:[accent] {0} stat.playtime = Spielzeit:[accent] {0}
stat.rank = Finaler Rang:[accent] {0} stat.rank = Finaler Rang:[accent] {0}
@@ -116,8 +119,10 @@ mods.none = [lightgray]Keine Mods gefunden!
mods.guide = Modding-Anleitung mods.guide = Modding-Anleitung
mods.report = Problem melden mods.report = Problem melden
mods.openfolder = Mod-Verzeichnis öffnen mods.openfolder = Mod-Verzeichnis öffnen
mods.viewcontent = Inhalt ansehen
mods.reload = Neu laden mods.reload = Neu laden
mods.reloadexit = Das Spiel wird jetzt beendet, um die Mod-Änderungen anzuwenden. mods.reloadexit = Das Spiel wird jetzt beendet, um die Mod-Änderungen anzuwenden.
mod.installed = [[Installiert]
mod.display = [gray]Mod:[orange] {0} mod.display = [gray]Mod:[orange] {0}
mod.enabled = [lightgray]Aktiviert mod.enabled = [lightgray]Aktiviert
mod.disabled = [scarlet]Deaktiviert mod.disabled = [scarlet]Deaktiviert
@@ -287,6 +292,7 @@ cancel = Abbruch
openlink = Link öffnen openlink = Link öffnen
copylink = Link kopieren copylink = Link kopieren
back = Zurück back = Zurück
max = Max
crash.export = Crash-Logs exportieren crash.export = Crash-Logs exportieren
crash.none = Keine Crash-Logs gefunden. crash.none = Keine Crash-Logs gefunden.
crash.exported = Crash-Logs wurden erfolgreich exportiert. crash.exported = Crash-Logs wurden erfolgreich exportiert.
@@ -306,6 +312,7 @@ cancelbuilding = [accent][[{0}][] um den Plan zu leeren
selectschematic = [accent][[{0}][] zum Auswählen+Kopieren selectschematic = [accent][[{0}][] zum Auswählen+Kopieren
pausebuilding = [accent][[{0}][] um das Bauen zu pausieren pausebuilding = [accent][[{0}][] um das Bauen zu pausieren
resumebuilding = [scarlet][[{0}][] um das Bauen fortzusetzen resumebuilding = [scarlet][[{0}][] um das Bauen fortzusetzen
enablebuilding = [scarlet][[{0}][] um zu bauen
showui = Bedienflächen versteckt.\nDrücke [accent][[{0}][], um sie wieder anzuzeigen. showui = Bedienflächen versteckt.\nDrücke [accent][[{0}][], um sie wieder anzuzeigen.
wave = [accent]Welle {0} wave = [accent]Welle {0}
wave.cap = [accent]Welle {0}/{1} wave.cap = [accent]Welle {0}/{1}
@@ -361,7 +368,6 @@ editor.center = Zur Mitte
workshop = Workshop workshop = Workshop
waves.title = Wellen waves.title = Wellen
waves.remove = Entfernen waves.remove = Entfernen
waves.never = <nie>
waves.every = alle waves.every = alle
waves.waves = Welle(n) waves.waves = Welle(n)
waves.perspawn = pro Spawn waves.perspawn = pro Spawn
@@ -390,7 +396,7 @@ editor.removeunit = Bereich entfernen
editor.teams = Teams editor.teams = Teams
editor.errorload = Fehler beim Laden der Datei:\n[accent]{0} editor.errorload = Fehler beim Laden der Datei:\n[accent]{0}
editor.errorsave = Fehler beim Speichern der Datei:\n[accent]{0} editor.errorsave = Fehler beim Speichern der Datei:\n[accent]{0}
editor.errorimage = Das ist ein Bild, keine Karte. Wechsle nicht den Dateityp und erwarte, dass es funktioniert.\n\nWenn du eine 'v3.5/build 40'-Karte importieren möchtest, benutze den 'Importiere Terrainbild'-Knopf im Editor. editor.errorimage = Das ist ein Bild, keine Karte.
editor.errorlegacy = Diese Karte ist zu alt und benutzt ein veraltetes Kartenformat, das nicht mehr unterstützt wird. editor.errorlegacy = Diese Karte ist zu alt und benutzt ein veraltetes Kartenformat, das nicht mehr unterstützt wird.
editor.errornot = Dies ist keine Kartendatei. editor.errornot = Dies ist keine Kartendatei.
editor.errorheader = Diese Karte ist entweder nicht gültig oder beschädigt. editor.errorheader = Diese Karte ist entweder nicht gültig oder beschädigt.
@@ -678,6 +684,7 @@ stat.drillspeed = Bohrgeschwindigkeit
stat.boosteffect = Verstärkungseffekt stat.boosteffect = Verstärkungseffekt
stat.maxunits = Max. aktive Einheiten stat.maxunits = Max. aktive Einheiten
stat.health = Lebenspunkte stat.health = Lebenspunkte
stat.armour = Panzer
stat.buildtime = Baudauer stat.buildtime = Baudauer
stat.maxconsecutive = Max. Konsekutive stat.maxconsecutive = Max. Konsekutive
stat.buildcost = Baukosten stat.buildcost = Baukosten
@@ -693,6 +700,7 @@ stat.lightningchance = Blitzwahr­schein­lich­keit
stat.lightningdamage = Blitzschaden stat.lightningdamage = Blitzschaden
stat.flammability = Brennbarkeit stat.flammability = Brennbarkeit
stat.radioactivity = Radioaktivität stat.radioactivity = Radioaktivität
stat.charge = Ladung
stat.heatcapacity = Hitzekapazität stat.heatcapacity = Hitzekapazität
stat.viscosity = Viskosität stat.viscosity = Viskosität
stat.temperature = Temperatur stat.temperature = Temperatur
@@ -720,6 +728,7 @@ bar.corereq = Kern-Basis erforderlich
bar.drillspeed = Bohrgeschwindigkeit: {0}/s bar.drillspeed = Bohrgeschwindigkeit: {0}/s
bar.pumpspeed = Pumpengeschwindigkeit: {0}/s bar.pumpspeed = Pumpengeschwindigkeit: {0}/s
bar.efficiency = Effizienz: {0}% bar.efficiency = Effizienz: {0}%
bar.boost = Beschleunigung: {0}%
bar.powerbalance = Strom: {0}/s bar.powerbalance = Strom: {0}/s
bar.powerstored = Gespeichert: {0}/{1} bar.powerstored = Gespeichert: {0}/{1}
bar.poweramount = Strom: {0} bar.poweramount = Strom: {0}
@@ -787,6 +796,7 @@ setting.shadows.name = Schatten
setting.blockreplace.name = Automatische Blockvorschläge setting.blockreplace.name = Automatische Blockvorschläge
setting.linear.name = Lineare Filterung setting.linear.name = Lineare Filterung
setting.hints.name = Tipps setting.hints.name = Tipps
setting.logichints.name = Logiktipps
setting.flow.name = Ressourcen-Fluss anzeigen setting.flow.name = Ressourcen-Fluss anzeigen
setting.backgroundpause.name = Im Hintergrund pausieren setting.backgroundpause.name = Im Hintergrund pausieren
setting.buildautopause.name = Bauen automatisch pausieren setting.buildautopause.name = Bauen automatisch pausieren
@@ -935,6 +945,7 @@ mode.custom = Angepasste Regeln
rules.infiniteresources = Unbegrenzte Ressourcen rules.infiniteresources = Unbegrenzte Ressourcen
rules.reactorexplosions = Reaktor-Explosionen rules.reactorexplosions = Reaktor-Explosionen
rules.coreincinerates = Kern verbrennt überflüssige Materialien
rules.schematic = Entwürfe erlaubt rules.schematic = Entwürfe erlaubt
rules.wavetimer = Wellen-Timer rules.wavetimer = Wellen-Timer
rules.waves = Wellen rules.waves = Wellen
@@ -955,7 +966,7 @@ rules.waitForWaveToEnd = Warten bis Welle endet
rules.dropzoneradius = Drop-Zonen-Radius:[lightgray] (Kacheln) rules.dropzoneradius = Drop-Zonen-Radius:[lightgray] (Kacheln)
rules.unitammo = Einheiten benötigen Munition rules.unitammo = Einheiten benötigen Munition
rules.title.waves = Wellen rules.title.waves = Wellen
rules.title.resourcesbuilding = Ressourcen & Gebäude rules.title.resourcesbuilding = Ressourcen & Blöcke
rules.title.enemy = Gegner rules.title.enemy = Gegner
rules.title.unit = Einheiten rules.title.unit = Einheiten
rules.title.experimental = Experimentell rules.title.experimental = Experimentell
@@ -1310,7 +1321,7 @@ item.coal.details = Scheint versteinerte Pflanzenmasse zu sein, die sich schon l
item.titanium.description = Wird im Flüssigkeitsbereich, im Bohrerbereich und für Flugzeuge vielfältig eingesetzt. item.titanium.description = Wird im Flüssigkeitsbereich, im Bohrerbereich und für Flugzeuge vielfältig eingesetzt.
item.thorium.description = Wird als festes Baumaterial oder radioaktiver Kraftstoff verwendet. item.thorium.description = Wird als festes Baumaterial oder radioaktiver Kraftstoff verwendet.
item.scrap.description = Wird in Pulverisierer und Schmelzer zu anderen Materialien bearbeitet. item.scrap.description = Wird in Pulverisierer und Schmelzer zu anderen Materialien bearbeitet.
item.scrap.details = Übriggebliebene Reste alter Gebäude oder Einheiten. item.scrap.details = Übriggebliebene Reste alter Blöcke oder Einheiten.
item.silicon.description = Wird in Solarzellen, komplizierter Elektronik und als zielsuchende Munition verwendet. item.silicon.description = Wird in Solarzellen, komplizierter Elektronik und als zielsuchende Munition verwendet.
item.plastanium.description = Wird für fortgeschrittene Einheiten, Isolation und Munition eingesetzt. item.plastanium.description = Wird für fortgeschrittene Einheiten, Isolation und Munition eingesetzt.
item.phase-fabric.description = Kann in Elektronik und selbstreparierende Blöcke verwendet werden. item.phase-fabric.description = Kann in Elektronik und selbstreparierende Blöcke verwendet werden.
@@ -1381,8 +1392,8 @@ block.inverted-sorter.description = Wie ein normaler Sortierer, aber gibt das au
block.router.description = Verteilt Materialien auf bis zu drei Richtungen. block.router.description = Verteilt Materialien auf bis zu drei Richtungen.
block.router.details = Ein nötiges Übel. Es ist nicht empfehlenswert, ihn neben Fabriken zu setzen, da er sich dort verstopfen kann. block.router.details = Ein nötiges Übel. Es ist nicht empfehlenswert, ihn neben Fabriken zu setzen, da er sich dort verstopfen kann.
block.distributor.description = Verteilt Materialien auf bis zu sieben Richtungen. block.distributor.description = Verteilt Materialien auf bis zu sieben Richtungen.
block.overflow-gate.description = Gibt Materialien nur zu den Seiten heraus, wenn der fordere Ausgang blockiert ist. Kann nicht neben anderen Überlauf- oder Unterlauftoren verwendet werden. block.overflow-gate.description = Gibt Materialien nur zu den Seiten heraus, wenn der fordere Ausgang blockiert ist.
block.underflow-gate.description = Das Gegenteil eines Überlauftors. Gibt Materialien nur nach vorne heraus, wenn die Seiten blockiert sind. Kann nicht neben anderen Überlauf- oder Unterlauftoren verwendet werden. block.underflow-gate.description = Das Gegenteil eines Überlauftors. Gibt Materialien nur nach vorne heraus, wenn die Seiten blockiert sind.
block.mass-driver.description = Ein Transportblock mit sehr hoher Reichweite. Sammelt mehrere Materialien und schießt sie zu einem verbundenen Massenbeschleuniger. block.mass-driver.description = Ein Transportblock mit sehr hoher Reichweite. Sammelt mehrere Materialien und schießt sie zu einem verbundenen Massenbeschleuniger.
block.mechanical-pump.description = Eine Pumpe, die keinen Strom benötigt. block.mechanical-pump.description = Eine Pumpe, die keinen Strom benötigt.
block.rotary-pump.description = Eine Pumpe, die Strom verbraucht. block.rotary-pump.description = Eine Pumpe, die Strom verbraucht.
@@ -1503,3 +1514,118 @@ unit.omura.description = Schießt eine Railgun mit hoher Reichweite, um Gegner z
unit.alpha.description = Beschützt den Scherbenkern vor Feinden. Baut Blöcke. unit.alpha.description = Beschützt den Scherbenkern vor Feinden. Baut Blöcke.
unit.beta.description = Beschützt den Fundamentkern vor Feinden. Baut Blöcke. unit.beta.description = Beschützt den Fundamentkern vor Feinden. Baut Blöcke.
unit.gamma.description = Beschützt den Nukleuskern vor Feinden. Baut Blöcke. unit.gamma.description = Beschützt den Nukleuskern vor Feinden. Baut Blöcke.
lst.read = Liest einen Wert aus einer verbundenen Spiecherzelle.
lst.write = Schreibt eine Zahl in einer verbundene Speicherzelle.
lst.print = Fügt Text zum Textspeicher hinzu.\nZeigt nichts an, bis [accent]Print Flush[] verwendet wird.
lst.draw = Fügt eine [accent]Draw[]-Aufgabe zum Bildspeicher hinzu.\nZeigt nichts an, bis [accent]Draw Flush[] verwendet wird.
lst.drawflush = Druckt [accent]Draw[]-Aufgaben aus dem Bildspeicher auf einen Bildschirm.
lst.printflush = Druckt [accent]Print[]-Aufgaben aus dem Textspeicher auf einen Nachrichtenblock.
lst.getlink = Gibt ein verbundenen Block wieder. Fängt bei 0 an.
lst.control = Steuert einen Block.
lst.radar = Findet Einheiten.
lst.sensor = Gibt Daten über einen Block oder eine Einheit wieder.
lst.set = Setzt eine Variable fest.
lst.operation = Verändert eine Variable.
lst.end = Springt wieder nach oben.
lst.jump = Falls die Bedingung erfüllt ist, wird woanders weitergemacht.
lst.unitbind = Speichert eine Einheit einer Sorte als [accent]@unit[].
lst.unitcontrol = Steuert [accent]@unit[].
lst.unitradar = Findet Einheiten in der Nähe von [accent]@unit[].
lst.unitlocate = Findet mit [accent]@unit[] bestimmte Positionen / Blöcke auf der ganzen Karte.
lenum.type = Englischer Name eines Blocks / einer Einheit. Ein Verteiler gibt [accent]@router[] wieder.\nKein string.
lenum.shoot = Schießt auf eine Position.
lenum.shootp = Schießt auf eine Einheit / einen Block und sagt deren Position voraus.
lenum.configure = Blockkonfiguration, z.B. das ausgewählte Item in einem Sortierer.
lenum.enabled = Ob der Block an oder aus ist.
lenum.color = Illuminiererfarbe.
lenum.always = Immer.
lenum.idiv = Division mit ganzen Zahlen.
lenum.div = Division.\nGibt bei Teilung durch null [accent]null[] zurück.
lenum.mod = Modulo.
lenum.equal = Prüft Gleichheit.\nNicht-"null" Objekte, die mit Zahlen verglichen werden, werden 1.
lenum.notequal = Prüft Ungleichheit.
lenum.strictequal = Prüft strenge Gleichheit.\nKann verwendet werden, um "null" zu finden.
lenum.shl = Bit-shift nacht links.
lenum.shr = Bit-shift nach rechts.
lenum.or = Bitwise ODER.
lenum.land = Logisches AND.
lenum.and = Bitwise UND.
lenum.not = Bitwise NOT.
lenum.xor = Bitwise XOR.
lenum.min = Die Größte von zwei Zahlen.
lenum.max = Die Kleinste von zwei Zahlen.
lenum.angle = Angle of vector in degrees.
lenum.len = Length of vector.
lenum.sin = Sinus in Grad.
lenum.cos = Cosinus in Grad.
lenum.tan = Tangens in Grad.
lenum.rand = Zufällige Zahl zwischen [0, <wert>).
lenum.log = Logarithmus (ln).
lenum.log10 = Logarithmus zur Basis 10.
lenum.noise = 2D rauschen.
lenum.abs = Betrag.
lenum.sqrt = Quadratwurzel.
lenum.any = Irgendeine Einheit.
lenum.ally = Freundliche Einheit.
lenum.attacker = Einheit mit Waffe.
lenum.enemy = Gegnerische Einheit.
lenum.boss = Bosseinheit.
lenum.flying = Lufteinheit.
lenum.ground = Bodeneinheit.
lenum.player = Spielergesteuerte Einheit.
lenum.ore = Erz.
lenum.damaged = Beschädigter, alliierter Block.
lenum.spawn = Gegnerischer Spawnpunkt.\nKann ein Kern oder eine Position sein.
lenum.building = Ein Block einer bestimmten Sorte.
lenum.core = Irgendein Kern.
lenum.storage = Speicherblock, z.B. ein Tresor.
sensor.in = Der Block / die Einheit.
radar.from = Block zu benutzen. [accent]Sensor[]-Reichweite hängt von der Blockreichweite ab.
radar.target = Einheitenfilter.
radar.and = Weitere Filter.
radar.order = Sortierreihenfolge der Ergebnisse. 0 bedeutet rückwärts.
radar.sort = Sortiermethode der Ergebnisse.
radar.output = Variable für das Ergebnis.
unitradar.target = Einheitenfilter.
unitradar.and = Weitere Filter.
unitradar.order = Sortierreihenfolge der Ergebnisse. 0 bedeutet rückwärts.
unitradar.sort = Sortiermethode der Ergebnisse.
unitradar.output = Variable für das Ergebnis.
control.of = Block, der gesteuert werden soll.
control.unit = Zieleinheit / Zielblock.
control.shoot = Ob geschossen werden soll.
unitlocate.enemy = Ob gegnerische Blöcke gesucht werden sollen.
unitlocate.found = Ob der Block gefunden wurde.
unitlocate.building = Variable für das Ergebnis.
unitlocate.outx = Variable für die X-Koordinate.
unitlocate.outy = Variable für die Y-Koordinate.
unitlocate.group = Gesuchter Blocktyp.
lenum.stop = Bewegung / Abbau / Bau abbrechen.
lenum.move = Geht zu diese Position.
lenum.approach = Geht auf einen Punkt mit einem bestimmten Radius zu.
lenum.pathfind = Geht zum gegnerischen Spawnpunkt.
lenum.target = Schießt auf eine Position.
lenum.targetp = Schießt auf eine Einheit und sagt deren Position voraus.
lenum.itemdrop = Items abwerfen.
lenum.itemtake = Items aus einem Block nehmen.
lenum.paydrop = Lässt einen Block / eine Einheit wieder fallen.
lenum.paytake = Hebt einen Block / eine kleine Einheit auf.
lenum.flag = Zahl, mit der eine Einheit identifiziert werden kann.
lenum.mine = Erz von einer Position abbauen.
lenum.build = Einen Block bauen.
lenum.getblock = Gibt den Blocktyp an den Koordinaten zurück.\nEinheiten müssen nah genug dran sein.\nFeste nicht-Blöcke sind [accent]@solid[].
lenum.within = Prüft, ob eine Einheit in einem Radius um einen Punkt ist.
lenum.boost = Aktiviert / deaktiviert den Boost.

View File

@@ -308,7 +308,7 @@ pausebuilding = Használd a(z) [accent][[{0}][] gombot, hogy megállítsd az ép
resumebuilding = Használd a(z) [scarlet][[{0}][] gombot, hogy folytasd az építkezést. resumebuilding = Használd a(z) [scarlet][[{0}][] gombot, hogy folytasd az építkezést.
showui = A kezelőfelület elrejtve.\nNyomja meg a(z) [accent][[{0}][] gombot a megjelenítéséhez. showui = A kezelőfelület elrejtve.\nNyomja meg a(z) [accent][[{0}][] gombot a megjelenítéséhez.
wave = [accent]{0}. Hullám wave = [accent]{0}. Hullám
wave.cap = [accent]{0}/{1}. Hullám wave.cap = [accent]{0}/{1} Hullám
wave.waiting = [lightgray]Következő hullám {0} wave.waiting = [lightgray]Következő hullám {0}
wave.waveInProgress = [lightgray]Hullám folyamatban wave.waveInProgress = [lightgray]Hullám folyamatban
waiting = [lightgray]Várakozás... waiting = [lightgray]Várakozás...
@@ -316,7 +316,7 @@ waiting.players = Várakozás a játékosokra...
wave.enemies = [lightgray]Fennmaradó ellenségek: {0} wave.enemies = [lightgray]Fennmaradó ellenségek: {0}
wave.enemycores = [accent]{0}[lightgray] Ellenséges magok wave.enemycores = [accent]{0}[lightgray] Ellenséges magok
wave.enemycore = [accent]{0}[lightgray] Ellenséges mag wave.enemycore = [accent]{0}[lightgray] Ellenséges mag
wave.enemy = [lightgray]{0} Magmaradt ellenség wave.enemy = [lightgray]{0} Megmaradt ellenség
wave.guardianwarn = Az őrző [accent]{0}[] hullám múlva érkezik. wave.guardianwarn = Az őrző [accent]{0}[] hullám múlva érkezik.
wave.guardianwarn.one = Az őrző [accent]{0}[] hullám múlva érkezik. wave.guardianwarn.one = Az őrző [accent]{0}[] hullám múlva érkezik.
loadimage = Fénykép betöltése loadimage = Fénykép betöltése

View File

@@ -41,11 +41,12 @@ be.ignore = Abaikan
be.noupdates = Tidak ada pembaruan yang ditemukan. be.noupdates = Tidak ada pembaruan yang ditemukan.
be.check = Cek versi baru be.check = Cek versi baru
mod.featured.title = Browser mod
mod.featured.dialog.title = Browser Mod mod.featured.dialog.title = Browser Mod
mods.browser.selected = Mod yang Dipilih mods.browser.selected = Mod yang Dipilih
mods.browser.add = Unduh Mod mods.browser.add = Unduh Mod
mods.github.open = Buka di GitHub mods.github.open = Buka di GitHub
mods.browser.sortdate = Urut berdasarkan waktu
mods.browser.sortstars = Urut berdasarkan bintang
schematic = Skema schematic = Skema
schematic.add = Menyimpan skema... schematic.add = Menyimpan skema...
@@ -90,6 +91,7 @@ joingame = Bermain Bersama
customgame = Permainan Modifikasi customgame = Permainan Modifikasi
newgame = Permainan Baru newgame = Permainan Baru
none = <kosong> none = <kosong>
none.found = [lightgray]<tidak ditemukan>
minimap = Peta Kecil minimap = Peta Kecil
position = Posisi position = Posisi
close = Tutup close = Tutup
@@ -1383,7 +1385,7 @@ block.inverted-sorter.description = Sama seperti penyortir, melainkan mengeluark
block.router.description = Menerima bahan dari satu arah dan mengeluarkannya ke 3 arah yang sama. Bisa juga menyimpan sejumlah bahan. Berguna untuk memisahkan bahan dari satu sumber ke target yang banyak. block.router.description = Menerima bahan dari satu arah dan mengeluarkannya ke 3 arah yang sama. Bisa juga menyimpan sejumlah bahan. Berguna untuk memisahkan bahan dari satu sumber ke target yang banyak.
block.router.details = Bisa sangat menggangu. Jangan meletakannya disamping input produksi, karena bisa tersumbat oleh output. block.router.details = Bisa sangat menggangu. Jangan meletakannya disamping input produksi, karena bisa tersumbat oleh output.
block.distributor.description = Pemisah canggih yang memisah item ke 7 arah berbeda bersamaan. block.distributor.description = Pemisah canggih yang memisah item ke 7 arah berbeda bersamaan.
block.overflow-gate.description = Kombinasi antara pemisah dan penyortir yang hanya mengeluarkan item ke kiri dan/atau ke kanan jika bagian depan tertutup. block.overflow-gate.description = Hanya mengeluarkan item ke kiri dan/atau ke kanan jika bagian depan tertutup.
block.underflow-gate.description = Kebalikan dari gerbang luap. Mengeluarkan ke depan jika kanan dan kiri tertutup. block.underflow-gate.description = Kebalikan dari gerbang luap. Mengeluarkan ke depan jika kanan dan kiri tertutup.
block.mass-driver.description = Blok item transportasi tercanggih. Membawa beberapa item dan menembaknya ke penggerak massal lainnya dari arah yang jauh. block.mass-driver.description = Blok item transportasi tercanggih. Membawa beberapa item dan menembaknya ke penggerak massal lainnya dari arah yang jauh.
block.mechanical-pump.description = Pompa murah dengan pengeluaran yang pelan, tetapi tidak mengkonsumsi tenaga. block.mechanical-pump.description = Pompa murah dengan pengeluaran yang pelan, tetapi tidak mengkonsumsi tenaga.

View File

@@ -4,10 +4,10 @@ contributors = 번역가와 기여자
discord = Mindustry Discord 서버에 가입하세요! discord = Mindustry Discord 서버에 가입하세요!
link.discord.description = Mindustry Discord 공식 대화방 link.discord.description = Mindustry Discord 공식 대화방
link.reddit.description = Mindustry 서브레딧 link.reddit.description = Mindustry 서브레딧
link.github.description = Mindustry 개발 홈페이지 link.github.description = Mindustry 소스코드
link.changelog.description = 업데이트 내용 목록 link.changelog.description = 업데이트 내용 목록
link.dev-builds.description = 불안정한 개발 버전 link.dev-builds.description = 불안정한 개발 버전
link.trello.description = 출시 예정 기능을 한다고 게시한 공식 Trello 보드 link.trello.description = 출시 예정 기능 계획을 게시한 공식 Trello 보드
link.itch.io.description = PC 다운로드가 있는 itch.io 페이지 link.itch.io.description = PC 다운로드가 있는 itch.io 페이지
link.google-play.description = Google Play 스토어 목록 link.google-play.description = Google Play 스토어 목록
link.f-droid.description = F-Droid 카탈로그 목록 link.f-droid.description = F-Droid 카탈로그 목록
@@ -22,7 +22,7 @@ gameover.disconnect = 연결 끊기
gameover.pvp = [accent]{0}[] 팀이 승리했습니다! gameover.pvp = [accent]{0}[] 팀이 승리했습니다!
gameover.waiting = [accent]다음 맵 기다리는 중... gameover.waiting = [accent]다음 맵 기다리는 중...
highscore = [accent]새로운 최고 점수! highscore = [accent]새로운 최고 점수!
copied = 복사 copied = 복사됨.
indev.notready = 이 부분은 아직 준비되지 않았습니다. indev.notready = 이 부분은 아직 준비되지 않았습니다.
indev.campaign = [accent]당신은 캠페인의 끝에 도달했습니다![]\n\n이것으로 캠페인에 있는 대부분의 콘텐츠는 끝났으며, 행성 간 여행은 향후 업데이트에 추가될 예정입니다. indev.campaign = [accent]당신은 캠페인의 끝에 도달했습니다![]\n\n이것으로 캠페인에 있는 대부분의 콘텐츠는 끝났으며, 행성 간 여행은 향후 업데이트에 추가될 예정입니다.
@@ -41,10 +41,13 @@ be.ignore = 무시
be.noupdates = 업데이트가 없습니다. be.noupdates = 업데이트가 없습니다.
be.check = 업데이트 확인 be.check = 업데이트 확인
mod.featured.dialog.title = 모드 탐색 (WIP) mods.browser = 모드 탐색
mods.browser.selected = 선택된 모드 mods.browser.selected = 선택된 모드
mods.browser.add = 모드 설치 mods.browser.add = 설치
mods.github.open = 깃허브 사이트 열기 mods.browser.reinstall = 재설치
mods.github.open = 레포지토리 보기
mods.browser.sortdate = 최근 업데이트
mods.browser.sortstars = 추천(스타) 수
schematic = 설계도 schematic = 설계도
schematic.add = 설계도 저장하기 schematic.add = 설계도 저장하기
@@ -54,7 +57,7 @@ schematic.exists = 해당 이름의 설계도가 이미 존재합니다.
schematic.import = 설계도 가져오기 schematic.import = 설계도 가져오기
schematic.exportfile = 파일 내보내기 schematic.exportfile = 파일 내보내기
schematic.importfile = 파일 가져오기 schematic.importfile = 파일 가져오기
schematic.browseworkshop = 창작마당 검색 schematic.browseworkshop = 창작마당 검색
schematic.copy = 클립 보드에 복사 schematic.copy = 클립 보드에 복사
schematic.copy.import = 클립 보드에서 가져오기 schematic.copy.import = 클립 보드에서 가져오기
schematic.shareworkshop = 창작마당에 공유 schematic.shareworkshop = 창작마당에 공유
@@ -116,8 +119,10 @@ mods.none = [lightgray]모드를 찾을 수 없습니다!
mods.guide = 모드 제작 가이드 mods.guide = 모드 제작 가이드
mods.report = 버그 제보하기 mods.report = 버그 제보하기
mods.openfolder = 폴더 열기 mods.openfolder = 폴더 열기
mods.viewcontent = 콘텐츠 보기
mods.reload = 새로 고침 mods.reload = 새로 고침
mods.reloadexit = 게임이 종료된 후 모드를 불러올 것입니다. mods.reloadexit = 게임이 종료된 후 모드를 불러올 것입니다.
mod.installed = [[설치됨]
mod.display = [gray]모드:[orange] {0} mod.display = [gray]모드:[orange] {0}
mod.enabled = [lightgray]활성화됨 mod.enabled = [lightgray]활성화됨
mod.disabled = [scarlet]비활성화됨 mod.disabled = [scarlet]비활성화됨
@@ -125,7 +130,7 @@ mod.disable = 비활성화
mod.content = 콘텐츠: mod.content = 콘텐츠:
mod.delete.error = 모드를 삭제할 수 없습니다. 파일이 사용 중일 수 있습니다. mod.delete.error = 모드를 삭제할 수 없습니다. 파일이 사용 중일 수 있습니다.
mod.requiresversion = [scarlet]필요한 최소 게임 버전: [accent]{0} mod.requiresversion = [scarlet]필요한 최소 게임 버전: [accent]{0}
mod.outdated = [scarlet]V6 버전과 호환되지 않음 (minGameVersion 105 이하인 모드는 사용할 수 없습니다.) mod.outdated = [scarlet]V6 버전과 호환되지 않음 (minGameVersion: 105 이상이 아님)
mod.missingdependencies = [scarlet]누락된 필요 모드: {0} mod.missingdependencies = [scarlet]누락된 필요 모드: {0}
mod.erroredcontent = [scarlet]콘텐츠 오류 mod.erroredcontent = [scarlet]콘텐츠 오류
mod.errors = 콘텐츠를 불러오는 중에 오류가 발생함. mod.errors = 콘텐츠를 불러오는 중에 오류가 발생함.
@@ -137,8 +142,8 @@ mod.reloadrequired = [scarlet]재시작 필요
mod.import = 모드 가져오기 mod.import = 모드 가져오기
mod.import.file = 파일 가져오기 mod.import.file = 파일 가져오기
mod.import.github = Github 에서 모드 가져오기 mod.import.github = Github 에서 모드 가져오기
mod.jarwarn = [scarlet]JAR 모드는 안전하지 않습니다.[]\n신뢰할 수 있는 모드 개발자에게서 얻은 모드만을 사용해야 합니다! mod.jarwarn = [scarlet]JAR 모드는 안전하지 않습니다.[]\n신뢰할 수 있는 개발자에게서 얻은 모드만을 사용해야 합니다!
mod.item.remove = 자원은[accent] '{0}' 모드의 일부입니다. 이를 제거하려면 해당 모드를 제거하세요. mod.item.remove = 아이템은[accent] '{0}' 모드의 일부입니다. 이를 제거하려면 해당 모드를 제거하세요.
mod.remove.confirm = 이 모드가 삭제될 것입니다. mod.remove.confirm = 이 모드가 삭제될 것입니다.
mod.author = [lightgray]제작자:[] {0} mod.author = [lightgray]제작자:[] {0}
mod.missing = 이 저장 파일에는 최근에 업데이트되었거나 현재 기기에 설치되지 않은 모드가 포함되어 있습니다. 저장 파일이 손상될 수 있습니다. 정말로 불러오시겠습니까?\n[lightgray]모드들:\n{0} mod.missing = 이 저장 파일에는 최근에 업데이트되었거나 현재 기기에 설치되지 않은 모드가 포함되어 있습니다. 저장 파일이 손상될 수 있습니다. 정말로 불러오시겠습니까?\n[lightgray]모드들:\n{0}
@@ -148,7 +153,7 @@ mod.scripts.disable = 이 기기는 스크립트가 있는 모드를 지원하
about.button = 정보 about.button = 정보
name = 닉네임 : name = 닉네임 :
noname = 먼저 [accent]닉네임[]을 설정하세요. noname = 먼저 [accent]플레이어 이름[]을 설정하세요.
planetmap = 행성 지도 planetmap = 행성 지도
launchcore = 코어 출격 launchcore = 코어 출격
filename = 파일 이름: filename = 파일 이름:
@@ -171,17 +176,17 @@ server.closing = [accent]서버를 닫는 중...
server.kicked.kick = 서버에서 추방되었습니다! server.kicked.kick = 서버에서 추방되었습니다!
server.kicked.whitelist = 당신은 이 서버의 화이트리스트에 등록되어 있지 않습니다. server.kicked.whitelist = 당신은 이 서버의 화이트리스트에 등록되어 있지 않습니다.
server.kicked.serverClose = 서버 닫힘. server.kicked.serverClose = 서버 닫힘.
server.kicked.vote = 당신은 투표로 추방되었습니다. 안녕히 가세요! server.kicked.vote = 당신은 투표로 추방되었습니다. 안녕히 가세요.
server.kicked.clientOutdated = 구버전 클라이언트입니다! 게임을 업데이트하세요! server.kicked.clientOutdated = 구버전 클라이언트입니다! 게임을 업데이트하세요!
server.kicked.serverOutdated = 구버전 서버입니다! 호스트에게 업데이트를 요청하세요! server.kicked.serverOutdated = 구버전 서버입니다! 호스트에게 업데이트를 요청하세요!
server.kicked.banned = 당신은 이 서버에서 영구적으로 차단되었습니다. server.kicked.banned = 당신은 이 서버에서 영구적으로 차단되었습니다.
server.kicked.typeMismatch = 이 서버는 현재 빌드 유형과 호환되지 않습니다. server.kicked.typeMismatch = 이 서버는 현재 빌드 호환되지 않습니다.
server.kicked.playerLimit = 서버의 인원이 꽉 찼습니다. 빈 슬롯이 생길 때까지 기다려주세요. server.kicked.playerLimit = 서버의 인원이 꽉 찼습니다. 빈 슬롯이 생길 때까지 기다려주세요.
server.kicked.recentKick = 최근에 추방되었습니다.\n추방 쿨타임이 끝날 때까지 기다리세요. server.kicked.recentKick = 최근에 추방되었습니다.\n추방 쿨타임이 끝날 때까지 기다리세요.
server.kicked.nameInUse = 이 서버에 해당 이름을 가진 사람이 있습니다. server.kicked.nameInUse = 이 서버에 해당 이름을 가진 사람이 있습니다.
server.kicked.nameEmpty = 설정된 닉네임이 없습니다. server.kicked.nameEmpty = 설정된 닉네임이 없습니다.
server.kicked.idInUse = 당신은 이미 이 서버에 있습니다! 두 개의 계정으로 연결하는 건 허용되지 않습니다. server.kicked.idInUse = 당신은 이미 이 서버에 있습니다! 두 개의 계정으로 연결하는 건 허용되지 않습니다.
server.kicked.customClient = 이 서버는 사용자 정의 빌드를 지원하지 않습니다. 공식 버전을 다운로드 하세요. 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}[]
@@ -204,7 +209,7 @@ servers.remote = 원격 서버
servers.global = 커뮤니티 서버 servers.global = 커뮤니티 서버
servers.disclaimer = 커뮤니티 서버는 개발자가 소유하거나 제어하지 [accent]않습니다[].\n\n서버들은 전연령대에 적합하지 않은 사용자 지정 콘텐츠를 보유할 수도 있습니다. servers.disclaimer = 커뮤니티 서버는 개발자가 소유하거나 제어하지 [accent]않습니다[].\n\n서버들은 전연령대에 적합하지 않은 사용자 지정 콘텐츠를 보유할 수도 있습니다.
servers.showhidden = 서버 숨기기 / 보이 servers.showhidden = 숨겨진 서버 보이기/숨기
server.shown = 서버 숨기기 server.shown = 서버 숨기기
server.hidden = 서버 보이기 server.hidden = 서버 보이기
@@ -217,7 +222,7 @@ trace.modclient = 사용자 지정 클라이언트: [accent]{0}
invalidid = 잘못된 클라이언트 ID입니다! 버그 보고서를 보내주세요. invalidid = 잘못된 클라이언트 ID입니다! 버그 보고서를 보내주세요.
server.bans = 차단 목록 server.bans = 차단 목록
server.bans.none = 차단된 플레이어를 찾을 수 없습니다! server.bans.none = 차단된 플레이어를 찾을 수 없습니다!
server.admins = 관리자 server.admins = 관리자
server.admins.none = 관리자를 찾을 수 없습니다! server.admins.none = 관리자를 찾을 수 없습니다!
server.add = 서버 추가 server.add = 서버 추가
server.delete = 정말로 이 서버를 삭제하시겠습니까? server.delete = 정말로 이 서버를 삭제하시겠습니까?
@@ -303,11 +308,12 @@ loading = [accent]불러오는중...
reloading = [accent]모드 새로고침하는중... reloading = [accent]모드 새로고침하는중...
saving = [accent]저장중... saving = [accent]저장중...
respawn = [accent][[{0}][] 키를 눌러 코어에서 부활 respawn = [accent][[{0}][] 키를 눌러 코어에서 부활
cancelbuilding = [accent][[{0}][] 를 눌러 건설 계획을 초기화 cancelbuilding = [accent][[{0}][] 를 눌러 건설 계획을 초기화
selectschematic = [accent][[{0}][] 를 눌러 선택+복사 selectschematic = [accent][[{0}][] 를 눌러 선택+복사
pausebuilding = [accent][[{0}][] 를 눌러 건설을 일시중지 pausebuilding = [accent][[{0}][] 를 눌러 건설을 일시중지
resumebuilding = [scarlet][[{0}][] 를 눌러 건설을 재개 resumebuilding = [scarlet][[{0}][] 를 눌러 건설을 재개
showui = [accent][[{0}][] 키를 눌러 UI를 활성 enablebuilding = [scarlet][[{0}][] 키를 눌러 건설을 활성
showui = UI가 숨겨졌습니다. [accent][[{0}][] 키를 눌러 UI를 활성화하세요.
wave = [accent]{0} 단계 wave = [accent]{0} 단계
wave.cap = [accent]단계 {0}/{1} wave.cap = [accent]단계 {0}/{1}
wave.waiting = 다음 단계까지[lightgray] {0}초 wave.waiting = 다음 단계까지[lightgray] {0}초
@@ -339,7 +345,7 @@ workshop.info = 아이템 정보
changelog = 변경점 (선택 사항): changelog = 변경점 (선택 사항):
eula = 스팀 EULA eula = 스팀 EULA
missing = 이 아이템은 삭제되거나 이동되었습니다.\n[lightgray]창작마당 목록이 자동으로 연결 해제되었습니다. missing = 이 아이템은 삭제되거나 이동되었습니다.\n[lightgray]창작마당 목록이 자동으로 연결 해제되었습니다.
publishing = [accent]업로드 중... publishing = [accent]게시 중...
publish.confirm = 이것을 게시하시겠습니까?[lightgray]창작마당 EULA에 동의해야 합니다. 그렇지 않으면 아이템이 표시되지 않습니다! publish.confirm = 이것을 게시하시겠습니까?[lightgray]창작마당 EULA에 동의해야 합니다. 그렇지 않으면 아이템이 표시되지 않습니다!
publish.error = 아이템 게시 오류: {0} publish.error = 아이템 게시 오류: {0}
steam.error = 스팀 서비스를 초기화하지 못했습니다.\n오류: {0} steam.error = 스팀 서비스를 초기화하지 못했습니다.\n오류: {0}
@@ -373,7 +379,7 @@ waves.edit = 편집
waves.copy = 클립보드로 복사 waves.copy = 클립보드로 복사
waves.load = 클립보드에서 불러오기 waves.load = 클립보드에서 불러오기
waves.invalid = 클립보드에 잘못된 단계 데이터가 있습니다. waves.invalid = 클립보드에 잘못된 단계 데이터가 있습니다.
waves.copied = 단계 복사됨 waves.copied = 단계 복사됨.
waves.none = 적 단계가 설정되지 않았습니다.\n비어있을 시 자동으로 기본 적 단계 데이터로 설정됩니다. waves.none = 적 단계가 설정되지 않았습니다.\n비어있을 시 자동으로 기본 적 단계 데이터로 설정됩니다.
#these are intentionally in lower case #these are intentionally in lower case
@@ -382,8 +388,8 @@ wavemode.totals = 총
wavemode.health = 체력 wavemode.health = 체력
editor.default = [lightgray]<기본값> editor.default = [lightgray]<기본값>
details = 설명 details = 설명...
edit = 편집 edit = 편집...
editor.name = 이름: editor.name = 이름:
editor.spawn = 유닛 생성 editor.spawn = 유닛 생성
editor.removeunit = 유닛 삭제 editor.removeunit = 유닛 삭제
@@ -413,7 +419,7 @@ editor.importfile = 파일 가져오기
editor.importfile.description = 외부 맵 파일 가져오기 editor.importfile.description = 외부 맵 파일 가져오기
editor.importimage = 사진 파일 가져오기 editor.importimage = 사진 파일 가져오기
editor.importimage.description = 외부 맵 사진 파일 가져오기 editor.importimage.description = 외부 맵 사진 파일 가져오기
editor.export = 내보내기 editor.export = 내보내기...
editor.exportfile = 파일 내보내기 editor.exportfile = 파일 내보내기
editor.exportfile.description = 맵 파일 내보내기 editor.exportfile.description = 맵 파일 내보내기
editor.exportimage = 지형 이미지 내보내기 editor.exportimage = 지형 이미지 내보내기
@@ -446,15 +452,15 @@ toolmode.drawteams.description = 블록 대신 선택한 팀으로 블록 팀을
filters.empty = [lightgray]필터가 없습니다! 아래 버튼을 눌러 하나를 추가하세요. filters.empty = [lightgray]필터가 없습니다! 아래 버튼을 눌러 하나를 추가하세요.
filter.distort = 왜곡 filter.distort = 왜곡
filter.noise = 노이즈 filter.noise = 노이즈
filter.enemyspawn = 적 소환지점 제한 filter.enemyspawn = 적 소환지점 선택
filter.spawnpath = 자동생성된 적 이동경로 폭 filter.spawnpath = 자동생성된 적 이동경로 폭
filter.corespawn = 코어 1개 제한 filter.corespawn = 코어 선택
filter.median = 중앙값 filter.median = 중앙값
filter.oremedian = 자원 중앙값 filter.oremedian = 광물 중앙값
filter.blend = 블렌드 filter.blend = 가장자리
filter.defaultores = 기본 자원 filter.defaultores = 기본 광물
filter.ore = 자원 filter.ore = 광물
filter.rivernoise = 협곡 노이즈 filter.rivernoise = 노이즈
filter.mirror = 거울 filter.mirror = 거울
filter.clear = 초기화 filter.clear = 초기화
filter.option.ignore = 무시 filter.option.ignore = 무시
@@ -463,19 +469,19 @@ filter.terrain = 지형
filter.option.scale = 크기 filter.option.scale = 크기
filter.option.chance = 배치 빈도 filter.option.chance = 배치 빈도
filter.option.mag = 크기 filter.option.mag = 크기
filter.option.threshold = 경계선 filter.option.threshold = 한계점
filter.option.circle-scale = 원 크기 filter.option.circle-scale = 원 크기
filter.option.octaves = 옥타브 filter.option.octaves = 옥타브
filter.option.falloff = 경사 filter.option.falloff = 경사
filter.option.angle = 각도 filter.option.angle = 각도
filter.option.amount = 개수 filter.option.amount = 개수
filter.option.block = 블록 filter.option.block = 블록
filter.option.floor = 배치할 타일 filter.option.floor = 타일
filter.option.flooronto = 대상 타일 filter.option.flooronto = 대상 타일
filter.option.target = 대상 타일 filter.option.target = 대상
filter.option.wall = filter.option.wall =
filter.option.ore = 자원 filter.option.ore = 광물
filter.option.floor2 = 2층 바닥 filter.option.floor2 = 2번째 타일
filter.option.threshold2 = 2번째 경계선 filter.option.threshold2 = 2번째 경계선
filter.option.radius = 반경 filter.option.radius = 반경
filter.option.percentile = 백분율 filter.option.percentile = 백분율
@@ -486,7 +492,7 @@ menu = 메뉴
play = 플레이 play = 플레이
campaign = 캠페인 campaign = 캠페인
load = 불러오기 load = 불러오기
save = 저장 save = 저장하기
fps = FPS: {0} fps = FPS: {0}
ping = Ping: {0}ms ping = Ping: {0}ms
memory = Mem: {0}mb memory = Mem: {0}mb
@@ -517,7 +523,7 @@ loadout = 출격
resources = 자원 resources = 자원
bannedblocks = 금지된 블록들 bannedblocks = 금지된 블록들
addall = 모두 추가 addall = 모두 추가
launch.from = 점령 코어 송신 지역 : [accent]{0} launch.from = 출격 출발지 : [accent]{0}
launch.destination = 목적지: {0} launch.destination = 목적지: {0}
configure.invalid = 해당 값은 0에서 {0} 사이의 숫자여야 합니다. configure.invalid = 해당 값은 0에서 {0} 사이의 숫자여야 합니다.
add = 추가... add = 추가...
@@ -532,7 +538,7 @@ error.alreadyconnected = 이미 접속 중입니다.
error.mapnotfound = 맵 파일을 찾을 수 없습니다! error.mapnotfound = 맵 파일을 찾을 수 없습니다!
error.io = 네트워크 I/O 오류. error.io = 네트워크 I/O 오류.
error.any = 알 수 없는 네트워크 오류. error.any = 알 수 없는 네트워크 오류.
error.bloom = 블룸 그래픽 효과를 적용하지 못했습니다.\n당신의 기기가 이 기능을 지원하지 않는 것일 수도 있습니다. error.bloom = 블룸 그래픽 효과를 적용하지 못했습니다.\n기기가 이 기능을 지원하지 않는 것일 수도 있습니다.
weather.rain.name = weather.rain.name =
weather.snow.name = weather.snow.name =
@@ -542,27 +548,27 @@ weather.fog.name = 안개
sectors.unexplored = [lightgray]미개척지 sectors.unexplored = [lightgray]미개척지
sectors.resources = 자원: sectors.resources = 자원:
sectors.production = 분당 자원 생산량: sectors.production = 생산량:
sectors.export = 분당 자원 수출량: sectors.export = 수출량:
sectors.time = 지역 진행 시간: sectors.time = 진행 시간:
sectors.threat = 지역 위험도: sectors.threat = 위험도:
sectors.wave = 진행 중 단계: sectors.wave = 단계:
sectors.stored = 저장된 자원 목록: sectors.stored = 저장:
sectors.resume = 재개 sectors.resume = 재개
sectors.launch = 출격 sectors.launch = 출격
sectors.select = 선택 sectors.select = 선택
sectors.nonelaunch = [lightgray]없음 (sun) sectors.nonelaunch = [lightgray]없음 (sun)
sectors.rename = 구역 이름 변경 sectors.rename = 구역 이름 변경
sectors.enemybase = [scarlet]적 기지 sectors.enemybase = [scarlet]적 기지
sectors.vulnerable = [scarlet]취약 sectors.vulnerable = [scarlet]취약
sectors.underattack = [scarlet]공격받고 있습니다! [accent]{0}% 손상됨. sectors.underattack = [scarlet]공격받고 있습니다! [accent]{0}% 손상됨.
sectors.survives = [accent]{0} 단계 이상 버티세요. sectors.survives = [accent]{0} 단계 이상 버티세요.
sectors.go = 지역 진입 sectors.go =진입
sector.curcapture = 점령 sector.curcapture = 지역 점령
sector.curlost = 잃은 지역 sector.curlost = 지역 잃음
sector.missingresources = [scarlet]자원 부족 sector.missingresources = [scarlet]자원 부족
sector.attacked = [accent]{0}[white] 지역이 공격받고 있습니다! sector.attacked = [accent]{0}[white] 지역이 공격받고 있습니다!
sector.lost = [accent]{0}[white] 지역을 잃었습니다... sector.lost = [accent]{0}[white] 지역을 잃었습니다!
#note: the missing space in the line below is intentional #note: the missing space in the line below is intentional
sector.captured = [accent]{0}[white] 지역을 점령했습니다! sector.captured = [accent]{0}[white] 지역을 점령했습니다!
@@ -578,7 +584,7 @@ planet.serpulo.name = 세르플로
planet.sun.name = 태양 planet.sun.name = 태양
sector.impact0078.name = 폐허 : Impact 0078 sector.impact0078.name = 폐허 : Impact 0078
sector.groundZero.name = Zero 전초기지 sector.groundZero.name = 전초기지
sector.craters.name = 크레이터 sector.craters.name = 크레이터
sector.frozenForest.name = 얼어붙은 숲 sector.frozenForest.name = 얼어붙은 숲
sector.ruinousShores.name = 파괴된 해안가 sector.ruinousShores.name = 파괴된 해안가
@@ -600,12 +606,12 @@ sector.saltFlats.description = 이 소금 사막은 매우 척박하여 자원
sector.craters.description = 물이 가득한 이 크레이터에는 옛 전쟁의 유물들이 쌓여있습니다.\n이곳을 다시 점령해 강화 유리를 제작하고 물을 끌어올려 포탑과 드릴에 공급하여 더 좋은 효율로 방어선을 강화하십시오. sector.craters.description = 물이 가득한 이 크레이터에는 옛 전쟁의 유물들이 쌓여있습니다.\n이곳을 다시 점령해 강화 유리를 제작하고 물을 끌어올려 포탑과 드릴에 공급하여 더 좋은 효율로 방어선을 강화하십시오.
sector.ruinousShores.description = 이 지역은 과거 해안방어기지로 사용되었습니다.\n그러나 지금은 기본구조물만 남아있으니 이 지역을 어서 신속히 수리하여 외부로 세력을 확장한 뒤, 잃어버린 기술을 다시 회수하십시오. sector.ruinousShores.description = 이 지역은 과거 해안방어기지로 사용되었습니다.\n그러나 지금은 기본구조물만 남아있으니 이 지역을 어서 신속히 수리하여 외부로 세력을 확장한 뒤, 잃어버린 기술을 다시 회수하십시오.
sector.stainedMountains.description = 더 안쪽에는 포자에 오염된 산맥이 있지만, 이곳은 아직 포자에 오염되지 않았습니다.\n이 지역에서 티타늄을 채굴하고 이것을 어떻게 사용하는지 배우십시오.\n\n적들은 이곳에서 더 강력합니다. 더 강한 유닛들이 나올 때까지 시간을 낭비하지 마십시오. sector.stainedMountains.description = 더 안쪽에는 포자에 오염된 산맥이 있지만, 이곳은 아직 포자에 오염되지 않았습니다.\n이 지역에서 티타늄을 채굴하고 이것을 어떻게 사용하는지 배우십시오.\n\n적들은 이곳에서 더 강력합니다. 더 강한 유닛들이 나올 때까지 시간을 낭비하지 마십시오.
sector.overgrowth.description = 이곳은 포자들의 근원과 가까이에 있는 과성장 지대입니다. 적이 이 곳에 전초기지를 설립했습니다. 거를 생산해 적의 코어를 박살 내고 우리가 잃어버린 것들을 되돌려받으십시오! sector.overgrowth.description = 이곳은 포자들의 근원과 가까이에 있는 과성장 지대입니다. 적이 이곳에 전초기지를 설립했습니다. 거를 생산해 적의 코어를 박살 내고 우리가 잃어버린 것들을 되돌려받으십시오!
sector.tarFields.description = 산지와 사막 사이에 있는 석유 생산지의 외곽 지역이며, 사용 가능한 타르가 매장되어 있는 희귀한 지역 중 하나입니다. 버려진 지역이지만 이곳에는 위험한 적군들이 있습니다. 그들을 과소평가하지 마십시오.\n\n[lightgray]석유 생산기술을 익히는 것이 도움이 될 것입니다. sector.tarFields.description = 산지와 사막 사이에 있는 석유 생산지의 외곽 지역이며, 사용 가능한 타르가 매장되어 있는 희귀한 지역 중 하나입니다. 버려진 지역이지만 이곳에는 위험한 적군들이 있습니다. 그들을 과소평가하지 마십시오.\n\n[lightgray]석유 생산기술을 익히는 것이 도움이 될 것입니다.
sector.desolateRift.description = 극도로 위험한 지역입니다. 자원은 풍부하지만, 사용 가능한 공간은 거의 없습니다. 코어 파괴의 위험성이 높으니 가능한 한 빨리 떠나십시오. 또한, 적의 공격 딜레이가 길다고 안심하지 마십시오. sector.desolateRift.description = 극도로 위험한 지역입니다. 자원은 풍부하지만, 사용 가능한 공간은 거의 없습니다. 코어 파괴의 위험성이 높으니 가능한 한 빨리 떠나십시오. 또한, 적의 공격 딜레이가 길다고 안심하지 마십시오.
sector.nuclearComplex.description = 과거 토륨의 생산, 연구와 처리를 위해 운영되었던 시설입니다. 지금은 그저 폐허로 전락했으며, 다수의 적이 배치된 지역입니다. 그들은 끊임없이 당신을 공격할 것입니다.\n\n[lightgray]토륨의 다양한 사용법을 연구하고 익히십시오. sector.nuclearComplex.description = 과거 토륨의 생산, 연구와 처리를 위해 운영되었던 시설입니다. 지금은 그저 폐허로 전락했으며, 다수의 적이 배치된 지역입니다. 그들은 끊임없이 당신을 공격할 것입니다.\n\n[lightgray]토륨의 다양한 사용법을 연구하고 익히십시오.
sector.fungalPass.description = 높은 산과 낮은 땅 사이의 전환 지역. 작은 적 정찰 기지가 여기에 있습니다.\n그것들을 파괴하세요.\n대거와 크롤러 유닛을 사용하여 두 개의 코어를 파괴하세요. sector.fungalPass.description = 높은 산과 낮은 땅 사이의 전환 지역. 작은 적 정찰 기지가 여기에 있습니다.\n그것들을 파괴하세요.\n대거와 크롤러 유닛을 사용하여 두 개의 코어를 파괴하세요.
sector.biomassFacility.description = 포자의 시작이 되는 지역입니다. 이 시설은 포자를 연구하고 그것들을 가장 처음 생산했습니다.\n이 시설에 기록된 기술을 배우고, 연료와 플라스터늄을 생산하기 위해 포자를 배양하세요. \n\n[lightgray]이 시설이 붕괴 후에, 시설 내에 배양되던 포자들이 외부로 방출되었습니다. 이로 인해 생태계 교란종인 포자가 지역 생태계에서 번식하게 되었고, 그 무엇도 이 무자비하고 작은 침략자에게 대항할 수 없었습니다. sector.biomassFacility.description = 포자의 시작이 되는 지역입니다. 이 시설은 포자를 연구하고 그것들을 가장 처음 생산했습니다.\n이 시설에 기록된 기술을 배우고, 연료와 플라스터늄을 생산하기 위해 포자를 배양하세요. \n\n[lightgray]이 시설이 붕괴 후에, 시설 내에 배양되던 포자들이 외부로 방출되었습니다. 이로 인해 생태계 교란종인 포자가 지역 생태계에서 번식하게 되었고, 그 무엇도 이 무자비하고 작은 침략자에게 대항할 수 없었습니다.
sector.windsweptIslands.description = 육지에서 멀리 떨어진 이곳에는 작은 군도가 있습니다. 이 지역을 조사해보면 한 때 [accent]플라스터늄[]을 생산한 흔적이 남아있습니다.\n\n몰려오는 적 해군을 막으며, 섬에 기지를 건설하고, 공장들을 연구하십시오. sector.windsweptIslands.description = 육지에서 멀리 떨어진 이곳에는 작은 군도가 있습니다. 이 지역을 조사해보면 한 때 [accent]플라스터늄[]을 생산한 흔적이 남아있습니다.\n\n몰려오는 적 해군을 막으며, 섬에 기지를 건설하고, 공장들을 연구하십시오.
sector.extractionOutpost.description = 적이 다른 지역에 자원을 보내기 위한 용도로 건설한 보급기지입니다.\n\n강력한 적들이 지키고 있거나, 침공해올 예정인 지역을 효과적으로 침공/수호하기 위해서는 우리도 이 수송 기술이 필요합니다. 적의 기지를 파괴하고, 그들의 수송 기술을 약탈하십시오. sector.extractionOutpost.description = 적이 다른 지역에 자원을 보내기 위한 용도로 건설한 보급기지입니다.\n\n강력한 적들이 지키고 있거나, 침공해올 예정인 지역을 효과적으로 침공/수호하기 위해서는 우리도 이 수송 기술이 필요합니다. 적의 기지를 파괴하고, 그들의 수송 기술을 약탈하십시오.
sector.impact0078.description = 이곳에는 시스템에 처음 진입한 우주 수송선의 잔해가 있습니다.\n\n우주선이 파괴된 잔해에서 최대한 많은 자원을 회수하고, 손상되지 않은 그들의 기술을 획득하세요. sector.impact0078.description = 이곳에는 시스템에 처음 진입한 우주 수송선의 잔해가 있습니다.\n\n우주선이 파괴된 잔해에서 최대한 많은 자원을 회수하고, 손상되지 않은 그들의 기술을 획득하세요.
@@ -613,9 +619,9 @@ sector.planetaryTerminal.description = 이 행성에서의 마지막 전투를
settings.language = 언어 settings.language = 언어
settings.data = 게임 데이터 settings.data = 게임 데이터
settings.reset = 설정 초기화 settings.reset = 기본값으로 초기화
settings.rebind = 조작키 설정 settings.rebind = 설정
settings.resetKey = 조작키 설정 초기화 settings.resetKey = 초기화
settings.controls = 조작 settings.controls = 조작
settings.game = 게임 settings.game = 게임
settings.sound = 소리 settings.sound = 소리
@@ -631,14 +637,14 @@ settings.clearcampaignsaves = 캠페인 맵 초기화
settings.clearcampaignsaves.confirm = 정말로 캠페인을 초기화하시겠습니까? settings.clearcampaignsaves.confirm = 정말로 캠페인을 초기화하시겠습니까?
paused = [accent]< 일시정지 > paused = [accent]< 일시정지 >
clear = 초기화 clear = 초기화
banned = [scarlet]차단 banned = [scarlet]금지
yes = O yes = O
no = X no = X
info.title = 정보 info.title = 정보
error.title = [scarlet]오류가 발생했습니다. error.title = [scarlet]오류가 발생했습니다
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.description = 특성
@@ -647,52 +653,54 @@ stat.output = 출력
stat.booster = 가속 stat.booster = 가속
stat.tiles = 필요한 타일 stat.tiles = 필요한 타일
stat.affinities = 친화력 stat.affinities = 친화력
stat.powercapacity = 전력량 stat.powercapacity = 전력
stat.powershot = 전력/발 stat.powershot = 전력/발
stat.damage = 공격력 stat.damage = 피해량
stat.targetsair = 공중 공격 stat.targetsair = 공중 조준
stat.targetsground = 지상 공격 stat.targetsground = 지상 조준
stat.itemsmoved = 이동 속도 stat.itemsmoved = 이동 속도
stat.launchtime = 발사 간격 stat.launchtime = 출격 간격
stat.shootrange = 사거리 stat.shootrange = 사거리
stat.size = 크기 stat.size = 크기
stat.displaysize = 화면 크기 stat.displaysize = 화면 크기
stat.liquidcapacity = 액체 용량 stat.liquidcapacity = 액체 용량
stat.powerrange = 전선 길이 stat.powerrange = 전선 길이
stat.linkrange = 감지 길이 stat.linkrange = 연결 길이
stat.instructions = 연산 속도 stat.instructions = 연산 속도
stat.powerconnections = 최대 연결 개수 stat.powerconnections = 최대 연결
stat.poweruse = 전력 요구량 stat.poweruse = 전력 요구량
stat.powerdamage = 전력/피해량 stat.powerdamage = 전력/피해량
stat.itemcapacity = 자원 용량 stat.itemcapacity = 자원 용량
stat.memorycapacity = 최대 변수 개수 stat.memorycapacity = 변수 용량
stat.basepowergeneration = 기본 발전량 stat.basepowergeneration = 기본 전력 발전량
stat.productiontime = 소요 시간 stat.productiontime = 소요 시간
stat.repairtime = 건물 완전 복구 시간 stat.repairtime = 건물 완전 수리 시간
stat.weapons = 무기 stat.weapons = 무기
stat.bullet = 탄환 stat.bullet = 탄환
stat.speedincrease = 속도 증가 stat.speedincrease = 속도 증가
stat.range = 사거리 stat.range = 사거리
stat.drilltier = 채굴 가능 자원 stat.drilltier = 채굴 가능
stat.drillspeed = 기본 채굴 속도 stat.drillspeed = 기본 채굴 속도
stat.boosteffect = 버프 효과 stat.boosteffect = 버프 효과
stat.maxunits = 최대 유닛 수 stat.maxunits = 최대 유닛 수
stat.health = 체력 stat.health = 체력
stat.armor = 방어력
stat.buildtime = 건설 시간 stat.buildtime = 건설 시간
stat.maxconsecutive = 최대 체인 길이 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 = 쿨타임
stat.explosiveness = 폭발성 stat.explosiveness = 폭발성
stat.basedeflectchance = 기본 반사 확률 stat.basedeflectchance = 기본 반사 확률
stat.lightningchance = 전격 확률 stat.lightningchance = 전격 확률
stat.lightningdamage = 전격 공격 stat.lightningdamage = 전격 피해
stat.flammability = 휘발 stat.flammability = 인화
stat.radioactivity = 방사성 stat.radioactivity = 방사성
stat.charge = 과충전율
stat.heatcapacity = 열 용량 stat.heatcapacity = 열 용량
stat.viscosity = 점성 stat.viscosity = 점성
stat.temperature = 온도 stat.temperature = 온도
@@ -700,10 +708,10 @@ stat.speed = 속도
stat.buildspeed = 건설 속도 stat.buildspeed = 건설 속도
stat.minespeed = 채굴 속도 stat.minespeed = 채굴 속도
stat.minetier = 채굴 티어 stat.minetier = 채굴 티어
stat.payloadcapacity = 화물 용량 stat.payloadcapacity = 화물 용량
stat.commandlimit = 지휘 한계 stat.commandlimit = 지휘 한계
stat.abilities = 능력 stat.abilities = 능력
stat.canboost = 부스터 stat.canboost = 이륙 가능
stat.flying = 비행 stat.flying = 비행
stat.ammouse = 탄약 사용 stat.ammouse = 탄약 사용
@@ -714,9 +722,9 @@ ability.unitspawn = {0} 공장
ability.shieldregenfield = 방어막 복구 필드 ability.shieldregenfield = 방어막 복구 필드
ability.movelightning = 가속 전격 ability.movelightning = 가속 전격
bar.drilltierreq = 더 좋은 드릴 필요 bar.drilltierreq = 더 좋은 드릴 필요
bar.noresources = 자원 부족 bar.noresources = 자원 부족
bar.corereq = 코어 필요 bar.corereq = 기본 코어 필요
bar.drillspeed = 드릴 속도: {0}/s bar.drillspeed = 드릴 속도: {0}/s
bar.pumpspeed = 펌프 속도: {0}/s bar.pumpspeed = 펌프 속도: {0}/s
bar.efficiency = 효율: {0}% bar.efficiency = 효율: {0}%
@@ -732,14 +740,14 @@ bar.unitcap = {0} {1}/{2}
bar.liquid = 액체 bar.liquid = 액체
bar.heat = 발열 bar.heat = 발열
bar.power = 전력 bar.power = 전력
bar.progress = 생산 진행도 bar.progress = 건설 진행도
bar.input = 입력 bar.input = 입력
bar.output = 출력 bar.output = 출력
units.processorcontrol = [lightgray]프로세서 제어 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.sapping = [stat]흡혈
bullet.homing = [stat]유도 bullet.homing = [stat]유도
@@ -747,7 +755,7 @@ bullet.shock = [stat]전격
bullet.frag = [stat]파편 bullet.frag = [stat]파편
bullet.buildingdamage = [stat]{0}%[lightgray] 건물 피해량 bullet.buildingdamage = [stat]{0}%[lightgray] 건물 피해량
bullet.knockback = [stat]{0}[lightgray] 넉백 bullet.knockback = [stat]{0}[lightgray] 넉백
bullet.pierce = [stat]{0}[lightgray] 관통 bullet.pierce = [stat]{0}[lightgray] 관통
bullet.infinitepierce = [stat]관통 bullet.infinitepierce = [stat]관통
bullet.healpercent = [stat]{0}[lightgray]% 회복 bullet.healpercent = [stat]{0}[lightgray]% 회복
bullet.freezing = [stat]빙결 bullet.freezing = [stat]빙결
@@ -759,7 +767,7 @@ unit.blocks = 블록
unit.blockssquared = 블록² unit.blockssquared = 블록²
unit.powersecond = 전력/초 unit.powersecond = 전력/초
unit.liquidsecond = 액체/초 unit.liquidsecond = 액체/초
unit.itemssecond = /초 unit.itemssecond = 자원/초
unit.liquidunits = 액체 unit.liquidunits = 액체
unit.powerunits = 전력 unit.powerunits = 전력
unit.degrees = unit.degrees =
@@ -775,19 +783,20 @@ unit.thousands = k
unit.millions = m unit.millions = m
unit.billions = b unit.billions = b
unit.pershot = /발 unit.pershot = /발
category.purpose = 기능 / 목적 category.purpose = 목적
category.general = 일반 category.general = 일반
category.power = 전력 category.power = 전력
category.liquids = 액체 category.liquids = 액체
category.items = 자원 category.items = 자원
category.crafting = 입력/출력 category.crafting = 입력/출력
category.function = 기능 category.function = 기능
category.optional = 보조 자원 category.optional = 선택적 향상
setting.landscape.name = 가로화면 잠금 setting.landscape.name = 가로화면 잠금
setting.shadows.name = 그림자 setting.shadows.name = 그림자
setting.blockreplace.name = 자동 블록 제안 setting.blockreplace.name = 자동 블록 제안
setting.linear.name = 선형 필터링 setting.linear.name = 선형 필터링
setting.hints.name = 힌트 setting.hints.name = 힌트 표시
setting.logichints.name = 로직 힌트 표시
setting.flow.name = 자원 흐름량 표시 setting.flow.name = 자원 흐름량 표시
setting.backgroundpause.name = 백그라운드에서 일시정지 setting.backgroundpause.name = 백그라운드에서 일시정지
setting.buildautopause.name = 건설 자동 일시정지 setting.buildautopause.name = 건설 자동 일시정지
@@ -811,14 +820,14 @@ setting.difficulty.hard = 혼돈
setting.difficulty.insane = 박멸 setting.difficulty.insane = 박멸
setting.difficulty.name = 난이도: setting.difficulty.name = 난이도:
setting.screenshake.name = 화면 흔들림 setting.screenshake.name = 화면 흔들림
setting.effects.name = 효과 보임 setting.effects.name = 효과 표시
setting.destroyedblocks.name = 파괴된 블록 표시 setting.destroyedblocks.name = 파괴된 블록 표시
setting.blockstatus.name = 블록 상태 표시 setting.blockstatus.name = 블록 상태 표시
setting.conveyorpathfinding.name = 컨베이어 배치할 때 자동으로 경로 찾기 setting.conveyorpathfinding.name = 컨베이어 배치 찾기
setting.sensitivity.name = 컨트롤러 감도 setting.sensitivity.name = 컨트롤러 감도
setting.saveinterval.name = 저장 간격 setting.saveinterval.name = 저장 간격
setting.seconds = {0}초 setting.seconds = {0}초
setting.milliseconds = {0}ms setting.milliseconds = {0} 밀리초
setting.fullscreen.name = 전체 화면 setting.fullscreen.name = 전체 화면
setting.borderlesswindow.name = 테두리 없는 창 모드[lightgray] (재시작이 필요할 수 있습니다) setting.borderlesswindow.name = 테두리 없는 창 모드[lightgray] (재시작이 필요할 수 있습니다)
setting.fps.name = FPS와 핑 표시 setting.fps.name = FPS와 핑 표시
@@ -836,7 +845,7 @@ setting.sfxvol.name = 효과음 크기
setting.mutesound.name = 소리 끄기 setting.mutesound.name = 소리 끄기
setting.crashreport.name = 익명으로 오류 보고서 자동 전송 setting.crashreport.name = 익명으로 오류 보고서 자동 전송
setting.savecreate.name = 자동 저장 활성화 setting.savecreate.name = 자동 저장 활성화
setting.publichost.name = 멀티플레이 공용 서버로 표시 setting.publichost.name = 공용 서버로 표시
setting.playerlimit.name = 플레이어 제한 setting.playerlimit.name = 플레이어 제한
setting.chatopacity.name = 채팅창 투명도 setting.chatopacity.name = 채팅창 투명도
setting.lasersopacity.name = 전선 투명도 setting.lasersopacity.name = 전선 투명도
@@ -856,7 +865,7 @@ category.view.name = 보기
category.multiplayer.name = 멀티플레이어 category.multiplayer.name = 멀티플레이어
category.blocks.name = 블록 선택 category.blocks.name = 블록 선택
command.attack = 공격 command.attack = 공격
command.rally = 순찰 command.rally = 집결
command.retreat = 후퇴 command.retreat = 후퇴
command.idle = 대기 command.idle = 대기
placement.blockselectkeys = \n[lightgray]단축키: [{0}, placement.blockselectkeys = \n[lightgray]단축키: [{0},
@@ -872,13 +881,13 @@ keybind.move_x.name = X축 이동
keybind.move_y.name = Y축 이동 keybind.move_y.name = Y축 이동
keybind.mouse_move.name = 커서를 따라서 이동 keybind.mouse_move.name = 커서를 따라서 이동
keybind.pan.name = 펜 보기 keybind.pan.name = 펜 보기
keybind.boost.name = 비행 keybind.boost.name = 이륙
keybind.schematic_select.name = 영역 설정 keybind.schematic_select.name = 영역 설정
keybind.schematic_menu.name = 설계도 메뉴 keybind.schematic_menu.name = 설계도 메뉴
keybind.schematic_flip_x.name = 설계도 X축 뒤집기 keybind.schematic_flip_x.name = 설계도 X축 뒤집기
keybind.schematic_flip_y.name = 설계도 Y축 뒤집기 keybind.schematic_flip_y.name = 설계도 Y축 뒤집기
keybind.category_prev.name = 이전 목록 keybind.category_prev.name = 이전 카테고리
keybind.category_next.name = 다음 목록 keybind.category_next.name = 다음 카테고리
keybind.block_select_left.name = 블록 왼쪽 선택 keybind.block_select_left.name = 블록 왼쪽 선택
keybind.block_select_right.name = 블록 오른쪽 선택 keybind.block_select_right.name = 블록 오른쪽 선택
keybind.block_select_up.name = 블록 위쪽 선택 keybind.block_select_up.name = 블록 위쪽 선택
@@ -903,7 +912,7 @@ keybind.pickupCargo.name = 화물 집기
keybind.dropCargo.name = 화물 내려놓기 keybind.dropCargo.name = 화물 내려놓기
keybind.command.name = 명령 keybind.command.name = 명령
keybind.shoot.name = 사격 keybind.shoot.name = 사격
keybind.zoom.name = 확대 keybind.zoom.name = 확대/축소
keybind.menu.name = 메뉴 keybind.menu.name = 메뉴
keybind.pause.name = 일시중지 keybind.pause.name = 일시중지
keybind.pause_building.name = 건설 일시정지/재개 keybind.pause_building.name = 건설 일시정지/재개
@@ -920,13 +929,13 @@ keybind.chat_history_prev.name = 이전 채팅 기록
keybind.chat_history_next.name = 다음 채팅 기록 keybind.chat_history_next.name = 다음 채팅 기록
keybind.chat_scroll.name = 채팅 스크롤 keybind.chat_scroll.name = 채팅 스크롤
keybind.chat_mode = 대화 대상 변경 keybind.chat_mode = 대화 대상 변경
keybind.drop_unit.name = 유닛 떨구 keybind.drop_unit.name = 유닛 내려놓
keybind.zoom_minimap.name = 미니맵 확대 keybind.zoom_minimap.name = 미니맵 확대
mode.help.title = 모드 설명 mode.help.title = 모드 설명
mode.survival.name = 생존 mode.survival.name = 생존
mode.survival.description = 기본 모드. 제한된 자원이 있으며, 단계가 자동으로 시작합니다.\n[gray]플레이하려면 맵에 적의 스폰지점이 필요합니다. mode.survival.description = 기본 모드. 제한된 자원이 있으며, 단계가 자동으로 시작합니다.\n[gray]플레이하려면 맵에 적의 스폰지점이 필요합니다.
mode.sandbox.name = 샌드박스 mode.sandbox.name = 샌드박스
mode.sandbox.description = 무한한 자원이 있으며, 단계 타이머가 없습니다. mode.sandbox.description = 무한한 자원이 있으며, 시간 제한이 없습니다.
mode.editor.name = 편집기 mode.editor.name = 편집기
mode.pvp.name = PvP mode.pvp.name = PvP
mode.pvp.description = 다른 플레이어와 현장에서 싸우십시오.\n[gray]플레이하려면 맵에 다른 색상의 코어가 2개 이상 있어야 합니다. mode.pvp.description = 다른 플레이어와 현장에서 싸우십시오.\n[gray]플레이하려면 맵에 다른 색상의 코어가 2개 이상 있어야 합니다.
@@ -939,7 +948,7 @@ rules.reactorexplosions = 원자로 폭발 허용
rules.coreincinerates = 코어 방화 비허용 rules.coreincinerates = 코어 방화 비허용
rules.schematic = 설계도 허용 rules.schematic = 설계도 허용
rules.wavetimer = 시간 제한이 있는 단계 rules.wavetimer = 시간 제한이 있는 단계
rules.waves = 일반 단계 rules.waves = 단계
rules.attack = 공격 모드 rules.attack = 공격 모드
rules.buildai = AI 건설 rules.buildai = AI 건설
rules.enemyCheat = 무한 AI (빨간팀) 자원 rules.enemyCheat = 무한 AI (빨간팀) 자원
@@ -948,26 +957,28 @@ rules.blockdamagemultiplier = 블록 공격력 배수
rules.unitbuildspeedmultiplier = 유닛 생산 속도 배수 rules.unitbuildspeedmultiplier = 유닛 생산 속도 배수
rules.unithealthmultiplier = 유닛 체력 배수 rules.unithealthmultiplier = 유닛 체력 배수
rules.unitdamagemultiplier = 유닛 공격력 배수 rules.unitdamagemultiplier = 유닛 공격력 배수
rules.unitcapvariable = 코어 유닛 제한 추가
rules.unitcap = 기본 유닛 제한
rules.enemycorebuildradius = 적 코어 건설 금지구역 범위:[lightgray] (타일) rules.enemycorebuildradius = 적 코어 건설 금지구역 범위:[lightgray] (타일)
rules.wavespacing = 단계 간격:[lightgray] (초) rules.wavespacing = 단계 간격:[lightgray] (초)
rules.buildcostmultiplier = 건설 자원소모 배수 rules.buildcostmultiplier = 건설 비용 배수
rules.buildspeedmultiplier = 건설 속도 배수 rules.buildspeedmultiplier = 건설 속도 배수
rules.deconstructrefundmultiplier = 해체 환불 배수 rules.deconstructrefundmultiplier = 철거 환불 배수
rules.waitForWaveToEnd = 한 단계가 끝날때까지 대기 rules.waitForWaveToEnd = 한 단계가 끝날때까지 대기
rules.dropzoneradius = 스폰 구역 범위: [lightgray] (타일) rules.dropzoneradius = 스폰 구역 범위: [lightgray] (타일)
rules.unitammo = 탄약 필요 rules.unitammo = 유닛 탄약 필요
rules.title.waves = 단계 rules.title.waves = 단계
rules.title.resourcesbuilding = 자원 & 건축 rules.title.resourcesbuilding = 자원 & 건축
rules.title.enemy = rules.title.enemy =
rules.title.unit = 유닛 rules.title.unit = 유닛
rules.title.experimental = 실험적인 기능 rules.title.experimental = 실험적인 기능
rules.title.environment = 환경 rules.title.environment = 환경
rules.lighting = 조명 rules.lighting = 조명 표시
rules.enemyLights = 상대에게 조명 표시 rules.enemyLights = 상대에게 조명 표시
rules.fire = 방화 rules.fire = 방화 허용
rules.explosions = 블록/유닛 폭발 데미지 rules.explosions = 블록/유닛 폭발 데미지
rules.ambientlight = 자연 조명 표시 rules.ambientlight = 자연 조명 표시
rules.weather = 날씨 rules.weather = 날씨 추가
rules.weather.frequency = 빈도: rules.weather.frequency = 빈도:
rules.weather.always = 항상 rules.weather.always = 항상
rules.weather.duration = 지속 시간: rules.weather.duration = 지속 시간:
@@ -1036,8 +1047,8 @@ unit.corvus.name = 코르버스
block.resupply-point.name = 보급 지점 block.resupply-point.name = 보급 지점
block.parallax.name = 패럴랙스 block.parallax.name = 패럴랙스
block.cliff.name = 언덕 block.cliff.name = 언덕
block.sand-boulder.name = 사암 block.sand-boulder.name = 사암 바위
block.basalt-boulder.name = 현무암 block.basalt-boulder.name = 현무암 바위
block.grass.name = 잔디 block.grass.name = 잔디
block.slag.name = 용암 block.slag.name = 용암
block.space.name = 우주 block.space.name = 우주
@@ -1262,19 +1273,19 @@ team.purple.name = 보라색 팀
hint.skip = 힌트 넘기기 hint.skip = 힌트 넘기기
hint.desktopMove = [accent][[WASD][] 키를 이용해 자신의 유닛을 조종하세요. hint.desktopMove = [accent][[WASD][] 키를 이용해 자신의 유닛을 조종하세요.
hint.zoom = [accent]마우스 스크롤[] 사용해 확대 또는 축소가 가능합니다. hint.zoom = [accent]마우스 스크롤[] 사용해 확대 또는 축소가 가능합니다.
hint.mine = \uf8c4 주변의 구리광석을 수동으로 채굴하려면 광석을 [accent]누르십시오[]. (추가설명)마우스가 있을 경우 마우스 오른쪽 클릭을 하면 채굴 중단이 가능합니다. hint.mine =\uf8c4 주변의 구리 광석을 수동으로 채굴하려면 광석을 [accent]누르십시오[]. (추가 설명) 마우스가 있으면 마우스 오른쪽 클릭을 하면 채굴 중단이 가능합니다.
hint.desktopShoot = [accent][[마우스 클릭][]으로 발사할수 있습니다. hint.desktopShoot = [accent][[마우스 클릭][]으로 발사할 수 있습니다.
hint.depositItems = 자원을 코어로 옮기려면, 당신의 기체의 자원을 코어로 끌어놓으세요. hint.depositItems = 자원을 코어로 옮기려면, 기체의 자원을 코어로 끌어놓으세요.
hint.respawn = 당신의 기체를 떠나려면 [accent][[V][]를 누르십시오. hint.respawn = 기체를 떠나려면 [accent][[V][]를 누르십시오.
hint.respawn.mobile = 당신은 유닛 혹은 포탑을 조종할 수 있습니다. 당신의 기체를 떠나려면 [accent]왼쪽 위에 있는 아바타를 누르십시오.[] hint.respawn.mobile = 유닛 혹은 포탑을 조종할 수 있습니다. 기체를 떠나려면 [accent]왼쪽 위에 있는 아바타를 누르십시오.[]
hint.desktopPause = 게임을 일시 정지/재시작하기 위해 [accent][[Space][]를 누르십시오. hint.desktopPause = 게임을 일시 정지/재시작하기 위해 [accent][[Space][]를 누르십시오.
hint.placeDrill = 드릴을 설치하려면 오른쪽 아래의 \ue85e [accent]드릴[]을 선택하고, \uf870 [accent]드릴[]을 선택해서 구리 광석 위를 누르십시오. hint.placeDrill = 드릴을 설치하려면 오른쪽 아래의 \ue85e [accent]드릴[]을 선택하고, \uf870 [accent]드릴[]을 선택해서 구리 광석 위를 누르십시오.
hint.placeDrill.mobile = 오른쪽 아래 메뉴의 \ue85e [accent]드릴[]을 선택하고, \uf870 [accent]드릴[] 선택해서 구리 광석 위를 누르십시오.\n\n설치를 완료하려면 오른쪽 아래의 \ue800 [accent]완료 버튼[]을 누르십시오. hint.placeDrill.mobile = 오른쪽 아래 메뉴의 \ue85e [accent] 드릴[]을 선택하고, \uf870 [accent]드릴[] 선택해서 구리 광석 위를 누르십시오.\n\n설치를 완료하려면 오른쪽 아래의 \ue800 [accent]완료 버튼[]을 누르십시오.
hint.placeConveyor = 컨베이어는 자원을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n클릭하거나 드래그로 다수의 컨베이어를 설치할 수 있습니다.\n클릭하고 놓지 않은 채로 마우스 [accent]휠을 돌리면 돌아갑니다. hint.placeConveyor = 컨베이어는 자원을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n클릭하거나 드래그로 다수의 컨베이어를 설치할 수 있습니다.\n클릭하고 놓지 않은 채로 마우스 [accent]휠을 돌리면 돌아갑니다.
hint.placeConveyor.mobile = 컨베이어는 자원을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n여러 개의 컨베이어를 놓으려면 손가락으로 누른 채로 끌어서 설치 범위를 지정하십시오. hint.placeConveyor.mobile = 컨베이어는 자원을 드릴에서 다른 블록으로 이동시켜줍니다. \ue814 [accent]분배[] 카테고리에서 \uf896 [accent]컨베이어[]를 선택하십시오.\n\n여러 개의 컨베이어를 놓으려면 손가락으로 누른 채로 끌어서 설치 범위를 지정하십시오.
hint.placeTurret = 적에게서 당신의 기지를 막아내려면 \uf861 [accent]포탑[]를 설치하십시오.\n\n포탑 탄약 필요 - 지금은 \uf838 구리가 필요합니다.\n컨베이어를 사용해 드릴에 구리를 공급하십시오. hint.placeTurret = 적에게서 기지를 막아내려면 \uf861 [accent]포탑[]를 설치하십시오.\n\n포탑 탄약 필요 - 지금은 \uf838 구리가 필요합니다.\n컨베이어를 사용해 드릴에 구리를 공급하십시오.
hint.breaking = 블록을 부수려면 [accent]오른클릭[]이나 드래그를 하십시오. hint.breaking = 블록을 부수려면 [accent]클릭[]이나 드래그를 하십시오.
hint.breaking.mobile = 블록을 부수려면 오른쪽 아래의 \ue817 [accent]망치[]를 눌러 해체 모드를 활성화하십시오.\n\n손가락으로 누른 채로 끌어서 해체 범위를 지정하십시오. hint.breaking.mobile = 블록을 부수려면 오른쪽 아래의 \ue817 [accent]망치[]를 눌러 해체 모드를 활성화하십시오.\n\n손가락으로 누른 채로 끌어서 해체 범위를 지정하십시오.
hint.research = 새 기술을 연구하려면 \ue875 [accent]연구[]버튼을 누르십시오. hint.research = 새 기술을 연구하려면 \ue875 [accent]연구[]버튼을 누르십시오.
hint.research.mobile = 새 기술을 연구하려면 \ue88c [accent]메뉴[] 아래의 \ue875 [accent]연구[]버튼을 누르십시오. hint.research.mobile = 새 기술을 연구하려면 \ue88c [accent]메뉴[] 아래의 \ue875 [accent]연구[]버튼을 누르십시오.
@@ -1285,7 +1296,7 @@ hint.launch.mobile = 충분한 자원을 모았으면, 오른쪽 아래의 \ue88
hint.schematicSelect = 블록을 복사하고 붙여넣으려면 [accent][[F][]를 누른 채로 끌어서 구역을 지정하십시오. \n\n [accent][[마우스 휠][]을 누르면 한 개의 블록만 복사할 수 있습니다. hint.schematicSelect = 블록을 복사하고 붙여넣으려면 [accent][[F][]를 누른 채로 끌어서 구역을 지정하십시오. \n\n [accent][[마우스 휠][]을 누르면 한 개의 블록만 복사할 수 있습니다.
hint.conveyorPathfind = [accent][[왼쪽 Ctrl][]을 누른 채로 컨베이어를 대각선으로 끌면 길을 자동으로 만들어줍니다. hint.conveyorPathfind = [accent][[왼쪽 Ctrl][]을 누른 채로 컨베이어를 대각선으로 끌면 길을 자동으로 만들어줍니다.
hint.conveyorPathfind.mobile = \ue844 [accent]diagonal mode[]를 활성화하고 컨베이어를 대각선으로 끌면 길을 자동으로 찾아줍니다. hint.conveyorPathfind.mobile = \ue844 [accent]diagonal mode[]를 활성화하고 컨베이어를 대각선으로 끌면 길을 자동으로 찾아줍니다.
hint.boost = 당신의 유닛과 같이 장애물을 넘어가려면 [accent][[L-Shift][]을 누르고 이동하십시오. \n\n 적은 수의 지상 유닛만 날 수 있습니다. hint.boost = 유닛과 같이 장애물을 넘어가려면 [accent][[L-Shift][]을 누르고 이동하십시오. \n\n 적은 수의 지상 유닛만 날 수 있습니다.
hint.command = 주변의 아군 유닛을 데리고 다니려면 비슷한 단계의 유닛 무리 주변에서 [accent][[G][]를 누르십시오. \n\n 지상 유닛을 데리고 다니기 위해서는 먼저 다른 지상 유닛을 조종하고 있어야 합니다. hint.command = 주변의 아군 유닛을 데리고 다니려면 비슷한 단계의 유닛 무리 주변에서 [accent][[G][]를 누르십시오. \n\n 지상 유닛을 데리고 다니기 위해서는 먼저 다른 지상 유닛을 조종하고 있어야 합니다.
hint.command.mobile = 아군 유닛을 데리고 다니려면 비슷한 단계의 유닛 무리 주변에서 [accent]빠르게 두 번 누르십시오[]. hint.command.mobile = 아군 유닛을 데리고 다니려면 비슷한 단계의 유닛 무리 주변에서 [accent]빠르게 두 번 누르십시오[].
hint.payloadPickup = 작은 블록이나 유닛을 집으려면 [accent][[[]를 누르십시오. hint.payloadPickup = 작은 블록이나 유닛을 집으려면 [accent][[[]를 누르십시오.
@@ -1295,10 +1306,10 @@ hint.payloadDrop.mobile = 다시 내려놓으려면 빈 공간에서 [accent]화
hint.waveFire = [accent]Wave[]포탑에 탄약으로 물을 넣으면 주변의 불을 자동으로 꺼줍니다. hint.waveFire = [accent]Wave[]포탑에 탄약으로 물을 넣으면 주변의 불을 자동으로 꺼줍니다.
hint.generator = \uf879 [accent]화력 발전기[]는 석탄을 태워서 주변 블록에 전력을 전달합니다.\n\n \uf87f 더 넓은 범위의 블록에 전력을 전달하려면 [accent]Power Nodes[]를 사용하십시오. hint.generator = \uf879 [accent]화력 발전기[]는 석탄을 태워서 주변 블록에 전력을 전달합니다.\n\n \uf87f 더 넓은 범위의 블록에 전력을 전달하려면 [accent]Power Nodes[]를 사용하십시오.
hint.guardian = [accent]수호자[] 유닛들은 방어력을 가집니다. [accent]구리[]와 [accent]납[] 같은 약한 탄약으로는 [scarlet]아무런 효과도 없습니다[].\n\n그런 수호자를 없애려면 높은 단계의 포탑 또는 \uf835 [accent]흑연[]을 탄약으로 넣은 \uf861듀오/\uf859살보를 사용하십시오. hint.guardian = [accent]수호자[] 유닛들은 방어력을 가집니다. [accent]구리[]와 [accent]납[] 같은 약한 탄약으로는 [scarlet]아무런 효과도 없습니다[].\n\n그런 수호자를 없애려면 높은 단계의 포탑 또는 \uf835 [accent]흑연[]을 탄약으로 넣은 \uf861듀오/\uf859살보를 사용하십시오.
hint.coreUpgrade = 코어는 [accent]상위 코어를 위에 설치함[]으로써 업그레이드할 수 있습니다.\n\n [accent]기반[] 코어를 [accent]조각[] 코어 위에 설치하십시오. 주변에 장애물이 없는지도 확인하십시오. hint.coreUpgrade = 코어는 [accent]상위 코어를 위에 설치함[]으로써 업그레이드할 수 있습니다.\n\n [accent]기반[] 코어를 [accent]조각[] 코어 위에 설치하십시오. 주변에 장애물이 없는지도 확인하십시오.
hint.presetLaunch = [accent]얼어붙은 숲[]과 같은 회색[accent]캠페인 지역[]은 어디에서나 출격해서 올 수 있습니다. 주변 지역을 점령하지 않아도 됩니다.\n\n이와 같은 [accent]네임드 지역[]들은 [accent]선택적[]입니다. hint.presetLaunch = [accent]얼어붙은 숲[]과 같은 회색[accent]캠페인 지역[]은 어디에서나 출격해서 올 수 있습니다. 주변 지역을 점령하지 않아도 됩니다.\n\n이와 같은 [accent]네임드 지역[]들은 [accent]선택적[]입니다.
hint.coreIncinerate = 코어가 자원으로 가득 찬 후에 받는 모든 자원들은 [accent]소각[]될 것입니다. hint.coreIncinerate = 코어가 자원으로 가득 찬 후에 받는 모든 자원들은 [accent]소각[]될 것입니다.
hint.coopCampaign = [accent]협동 캠페인[]을 할 , 현재 맵에서 생산된 자원들은 [accent]당신의 캠페인 지역으로[]도 보내집니다.\n\n호스트가 새로 해금한 모든 것들도 가져갑니다. hint.coopCampaign = [accent]협동 캠페인[]을 할 , 현재 맵에서 생산된 자원들은 [accent]캠페인 지역[]으로도 보내집니다.\n\n호스트가 새로 해금한 모든 것들도 가져갑니다.
item.copper.description = 가장 기본적인 건설 재료. 모든 유형의 블록에서 광범위하게 사용됩니다. item.copper.description = 가장 기본적인 건설 재료. 모든 유형의 블록에서 광범위하게 사용됩니다.
item.copper.details = 평범한 구리. 세르플로에 비정상적으로 많이 분포합니다. 별다른 보강재 없이는 구조적 문제 때문에 내구성이 비교적 약합니다. item.copper.details = 평범한 구리. 세르플로에 비정상적으로 많이 분포합니다. 별다른 보강재 없이는 구조적 문제 때문에 내구성이 비교적 약합니다.
@@ -1315,9 +1326,9 @@ item.scrap.description = 오래된 건물과 유닛의 남은 잔해. 미량의
item.scrap.details = 오래된 구조물과 유닛의 잔해. item.scrap.details = 오래된 구조물과 유닛의 잔해.
item.silicon.description = 매우 유용한 반도체. 복잡한 전자 장치나 유도탄에 사용됩니다. item.silicon.description = 매우 유용한 반도체. 복잡한 전자 장치나 유도탄에 사용됩니다.
item.plastanium.description = 고급 기체 및 파편화 탄약에 사용되는 가볍고 연성이 있는 재료입니다. item.plastanium.description = 고급 기체 및 파편화 탄약에 사용되는 가볍고 연성이 있는 재료입니다.
item.phase-fabric.description = 최첨단 전자 제품과 자수리 기술에 사용되는 거의 무중력에 가까운 물질입니다. item.phase-fabric.description = 최첨단 전자 제품과 자수리 기술에 사용되는 거의 무중력에 가까운 물질입니다.
item.surge-alloy.description = 독특한 전기적 특성을 가진 고급 합금. item.surge-alloy.description = 독특한 전기적 특성을 가진 고급 합금.
item.spore-pod.description = 산업 목적을 위해 대기 농도에서 합성된 포자 버섯. 석유, 폭발물 연료로 전환하는 데 사용됩니다. 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 = 소이 무기에서 사용되는 가연성 매우 높은 물질.
@@ -1327,14 +1338,14 @@ liquid.slag.description = 다양한 종류의 금속들이 함께 섞여 녹아
liquid.oil.description = 고급 재료 생산에 사용되는 액체. 석탄으로 전환하거나 무기로 뿌려서 불을 지를 수 있습니다. liquid.oil.description = 고급 재료 생산에 사용되는 액체. 석탄으로 전환하거나 무기로 뿌려서 불을 지를 수 있습니다.
liquid.cryofluid.description = 물과 티타늄으로 만든 비부식성 액체. 열용량이 매우 높으며 냉각수로 광범위하게 사용됩니다. liquid.cryofluid.description = 물과 티타늄으로 만든 비부식성 액체. 열용량이 매우 높으며 냉각수로 광범위하게 사용됩니다.
block.resupply-point.description = 주변 유닛들에 구리 탄약을 보급합니다. 배터리 전력이 필요한 유닛들은 호환되지 않습니다. block.resupply-point.description = 주변 유닛들에 구리 탄약을 보급합니다. 배터리 전력이 필요한 유닛들은 호환되지 않습니다.
block.armored-conveyor.description = 앞으로 자원들을 운반합니다. 측면에서 자원들을 받아들이지 않습니다. block.armored-conveyor.description = 앞으로 자원들을 운반합니다. 측면에서 자원들을 받아들이지 않습니다.
block.illuminator.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 = 석탄을 흑연으로 압축합니다. 냉각수로써 물이 필요합니다.
block.silicon-smelter.description = 석탄과 모래로부터 실리콘을 정제합니다. block.silicon-smelter.description = 석탄과 모래로부터 실리콘을 정제합니다.
block.kiln.description = 모래와 납을 강화 유리로 련합니다. block.kiln.description = 모래와 납을 강화 유리로 련합니다.
block.plastanium-compressor.description = 석유와 티타늄으로 플라스터늄을 생산합니다. block.plastanium-compressor.description = 석유와 티타늄으로 플라스터늄을 생산합니다.
block.phase-weaver.description = 토륨과 모래로 메타를 합성합니다. block.phase-weaver.description = 토륨과 모래로 메타를 합성합니다.
block.alloy-smelter.description = 티타늄, 납, 실리콘, 구리를 결합하여 설금을 생산합니다. block.alloy-smelter.description = 티타늄, 납, 실리콘, 구리를 결합하여 설금을 생산합니다.
@@ -1347,7 +1358,7 @@ 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 = 모든 자원을 파괴합니다. 샌드박스 전용.
@@ -1361,8 +1372,8 @@ block.plastanium-wall.description = 전격 공격을 흡수하고 전력 노드
block.plastanium-wall-large.description = 전격 공격을 흡수하고 전력 노드의 자동 연결을 차단하는 특수 유형의 벽.\n여러 타일을 차지합니다. block.plastanium-wall-large.description = 전격 공격을 흡수하고 전력 노드의 자동 연결을 차단하는 특수 유형의 벽.\n여러 타일을 차지합니다.
block.thorium-wall.description = 강력한 방어 블록.\n적으로부터 적절한 보호를 할 수 있습니다. block.thorium-wall.description = 강력한 방어 블록.\n적으로부터 적절한 보호를 할 수 있습니다.
block.thorium-wall-large.description = 강력한 방어 블록.\n적으로부터 적절한 보호를 할 수 있습니다.\n여러 타일을 차지합니다. block.thorium-wall-large.description = 강력한 방어 블록.\n적으로부터 적절한 보호를 할 수 있습니다.\n여러 타일을 차지합니다.
block.phase-wall.description = 특수 메타기반 반사 화합물로 코팅된 벽. 총알 대부분을 반사시킵니다. block.phase-wall.description = 특수 메타기반 반사 화합물로 코팅된 벽. 총알 대부분을 반사니다.
block.phase-wall-large.description = 특수 메타기반 반사 화합물로 코팅된 벽. 총알 대부분을 반사시킵니다.\n여러 타일을 차지합니다. block.phase-wall-large.description = 특수 메타기반 반사 화합물로 코팅된 벽. 총알 대부분을 반사니다.\n여러 타일을 차지합니다.
block.surge-wall.description = 내구성이 매우 강한 방어 블록.\n총탄이 날아오면 충전량을 높여 무작위로 방출합니다. block.surge-wall.description = 내구성이 매우 강한 방어 블록.\n총탄이 날아오면 충전량을 높여 무작위로 방출합니다.
block.surge-wall-large.description = 내구성이 매우 강한 방어 블록.\n총탄이 날아오면 충전량을 높여 무작위로 방출합니다.\n여러 타일을 차지합니다. block.surge-wall-large.description = 내구성이 매우 강한 방어 블록.\n총탄이 날아오면 충전량을 높여 무작위로 방출합니다.\n여러 타일을 차지합니다.
block.door.description = 작은 문. 탭 하여 열거나 닫을 수 있습니다. block.door.description = 작은 문. 탭 하여 열거나 닫을 수 있습니다.
@@ -1386,13 +1397,13 @@ block.distributor.description = 고급 분배기. 자원을 최대 7개의 다
block.overflow-gate.description = 전면 경로가 차단된 경우에만 왼쪽과 오른쪽으로 출력됩니다. block.overflow-gate.description = 전면 경로가 차단된 경우에만 왼쪽과 오른쪽으로 출력됩니다.
block.underflow-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 = 펄스 파이프와 같은 속도로 이동하지만 더 높은 방어력을 가지고 있습니다. 측면에서 액체들을 받아들이지 않습니다.\n액체가 누설하지 않습니다.
block.liquid-router.description = 한 방향에서 액체를 받아 최대 3개의 다른 방향으로 동일하게 출력합니다. 일정량의 액체를 저장할 수도 있으며 한 소스에서 여러 대상으로 액체를 분할하는 데 유용합니다. block.liquid-router.description = 한 방향에서 액체를 받아 최대 3개의 다른 방향으로 같이 출력합니다. 일정량의 액체를 저장할 수도 있으며 한 소스에서 여러 대상으로 액체를 나누는 데 유용합니다.
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 = 고급 액체 운송 블록. 지형이나 건물을 넘어 최대 3개 타일 위로 액체를 운반할 수 있습니다.
@@ -1401,7 +1412,7 @@ 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 = 열이 있는 곳에 설치하면 전력이 생성됩니다.
@@ -1414,7 +1425,7 @@ 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 = 대기 중의 작은 농도의 포자를 산업용 포자로 배양합니다.
@@ -1428,33 +1439,33 @@ block.core-nucleus.description = 기지의 핵심입니다. 방어력이 매우
block.core-nucleus.details = 세 번째, 궁극의 버전. 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 = 코어 출격 없이도 자원을 묶어 출격시킬 수 있습니다. block.launch-pad.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 = 주변 적에게 3개의 단거리 관통 레이저를 발사합니다. block.fuse.description = 주변 적에게 3개의 단거리 관통 레이저를 발사합니다.
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.foreshadow.description = 장거리에 걸친 거대한 단일 목표 저격탄을 발사합니다. block.foreshadow.description = 장거리에 걸친 거대한 단일 목표 저격탄을 발사합니다.
block.repair-point.description = 인근에 가장 가까운 유닛을 지속적으로 치료합니다. block.repair-point.description = 인근에 가장 가까운 유닛을 지속해서 치료합니다.
block.segment.description = 날아오는 발사체를 요격합니다. 큰 발사체에겐 조준하지 않습니다. block.segment.description = 날아오는 발사체를 요격합니다. 큰 발사체 조준하지 않습니다.
block.parallax.description = 공중 목표물을 끌어오는 견인 광선을 발사하며, 견인 과정에서 데미지를 줍니다. block.parallax.description = 공중 목표물을 끌어오는 견인 광선을 발사하며, 견인 과정에서 데미지를 줍니다.
block.tsunami.description = 적에게 강력한 액체 줄기를 발사합니다. 물이 공급되면 자동으로 주변의 화재를 진압합니다. block.tsunami.description = 적에게 강력한 액체 줄기를 발사합니다. 물이 공급되면 자동으로 주변의 화재를 진압합니다.
block.silicon-crucible.description = 추가적으로 파이라타이트를 사용하여 더 높은 온도에서 석탄과 모래를 제련합니다. 뜨거운 곳에서 더 효율적입니다. block.silicon-crucible.description = 추가로 파이라타이트를 사용하여 더 높은 온도에서 석탄과 모래를 제련합니다. 뜨거운 곳에서 더 효율적입니다.
block.disassembler.description = 광재를 낮은 확률로 미량의 희귀한 광물들로 분리합니다. 토륨을 생산할 수 있습니다. block.disassembler.description = 광재를 낮은 확률로 미량의 희귀한 광물들로 분리합니다. 토륨을 생산할 수 있습니다.
block.overdrive-dome.description = 인근 블록들을 과부하시킵니다. 작동하기 위해 실리콘과 메타가 필요합니다. block.overdrive-dome.description = 인근 블록들을 과부하시킵니다. 작동하기 위해 실리콘과 메타가 필요합니다.
block.payload-conveyor.description = 유닛이나 공장같이 큰 화물들을 운반합니다. block.payload-conveyor.description = 유닛이나 공장같이 큰 화물들을 운반합니다.
block.payload-router.description = 3가지 방향으로 번갈아서 화물들을 운반합니다. block.payload-router.description = 3가지 방향으로 번갈아서 화물들을 운반합니다.
block.command-center.description = 4개의 명령어로 유닛 행동을 제어합니다. block.command-center.description = 4개의 명령어로 유닛 행동을 제어합니다.
block.ground-factory.description = 지상 유닛들을 생산합니다. 생산된 유닛들은 바로 사용될 수 있고, 또는 강화를 위해 재구성기에 들어가질 수 있습니다. block.ground-factory.description = 지상 유닛들을 생산합니다. 생산된 유닛들은 바로 사용될 수 있고, 또는 강화를 위해 재구성기에 들어가질 수 있습니다.
block.air-factory.description = 공중 유닛들을 생산합니다. 생산된 유닛들은 바로 사용될 수 있고, 또는 강화를 위해 재구성기에 들어가질 수 있습니다. block.air-factory.description = 공중 유닛들을 생산합니다. 생산된 유닛들은 바로 사용될 수 있고, 또는 강화를 위해 재구성기에 들어가질 수 있습니다.
block.naval-factory.description = 해상 유닛들을 생산합니다. 생산된 유닛들은 바로 사용될 수 있고, 또는 강화를 위해 재구성기에 들어가질 수 있습니다. block.naval-factory.description = 해상 유닛들을 생산합니다. 생산된 유닛들은 바로 사용될 수 있고, 또는 강화를 위해 재구성기에 들어가질 수 있습니다.
@@ -1505,3 +1516,127 @@ unit.omura.description = 적에게 장거리 관통 레일건을 발사합니다
unit.alpha.description = 적으로부터 코어: 조각을 방어합니다. 구조물을 짓습니다. unit.alpha.description = 적으로부터 코어: 조각을 방어합니다. 구조물을 짓습니다.
unit.beta.description = 적으로부터 코어: 기반을 방어합니다. 구조물을 짓습니다. unit.beta.description = 적으로부터 코어: 기반을 방어합니다. 구조물을 짓습니다.
unit.gamma.description = 적으로부터 코어: 핵심을 방어합니다. 구조물을 짓습니다. unit.gamma.description = 적으로부터 코어: 핵심을 방어합니다. 구조물을 짓습니다.
lst.read = 연결된 메모리 셀에서 숫자 읽기
lst.write = 연결된 메모리 셀에 숫자 쓰기
lst.print = 프린트 버퍼에 텍스트 추가하기\n[accent]Print Flush[]가 사용되기 전까진 아무것도 보여주지 않습니다.
lst.draw = 드로잉 버퍼에 실행문 추가하기\n[accent]Draw Flush[]가 사용되기 전까진 아무것도 보여주지 않습니다.
lst.drawflush = 대기중인 [accent]Draw[]실행문을 디스플레이에 출력하기
lst.printflush = 대기중인 [accent]Print[]실행문을 메시지 블록에 출력하기
lst.getlink = 순서별로 프로세서 연결 가져오기. 0부터 시작
lst.control = 건물 조종하기
lst.radar = 건물 주변의 유닛 검색하기
lst.sensor = 건물 또는 유닛의 정보 얻기
lst.set = 변수 선언/할당하기
lst.operation = 1~2개의 변수로 연산자하기
lst.end = 실행줄의 가장 위로 점프하기
lst.jump = 조건부로 다른 실행문으로 점프하기
lst.unitbind = type 옆에 있는 유닛을 지정하고, [accent]@unit[]에 저장하기
lst.unitcontrol = 현재 지정된 유닛을 조종하기
lst.unitradar = 현재 지정된 유닛 주변의 유닛 검색하기
lst.unitlocate = 특정 유형의 위치/건물을 지도상에서 찾기\n지정된 유닛이 필요합니다.
lenum.type = 건물/유닛의 타입\n예로 분배기는 [accent]@router[]를 반환할 것입니다.\n문자열이 아니라.
lenum.shoot = 특정 위치에 발사
lenum.shootp = 목표물 속도를 예측하여 발사
lenum.configure = 필터의 아이템같은 건물의 설정
lenum.enabled = 블록의 활성 여부
lenum.color = 조명 색 설정
lenum.always = 항상 참
lenum.idiv = 정수 나누기
lenum.div = 나누기\n0으로 나누면 [accent]null[]을 반환합니다.
lenum.mod = 나머지
lenum.equal = 동치 비교. 형변환 가능\nNull이 아닌 객체가 숫자와 비교할려면 1이 되고, Null이면 0이 됩니다.
lenum.notequal = 동치 부정. 형변환 가능
lenum.strictequal = 엄격한 동치 비교. 형변환 불가능\n[accent]null[]를 확인하는데 쓸 수 있습니다.
lenum.shl = 왼쪽으로 비트 이동
lenum.shr = 오른쪽으로 비트 이동
lenum.or = 비트연산자 OR
lenum.land = 논리연산자 AND
lenum.and = 비트연산자 AND
lenum.not = 비트연산자 NOT
lenum.xor = 비트연산자 XOR
lenum.min = 두 수의 최솟값
lenum.max = 두 수의 최댓값
lenum.angle = 벡터의 각(도)
lenum.len = 벡터의 길이
lenum.sin = 사인(도)
lenum.cos = 코사인(도)
lenum.tan = 탄젠트(도)
#not a typo, look up 'range notation'
lenum.rand = 범위 내 난수[0 ~ 값)
lenum.log = 자연 로그(진수)
lenum.log10 = 상수 로그
lenum.noise = 2D 심플렉스 노이즈
lenum.abs = 절댓값
lenum.sqrt = 제곱근
lenum.any = 유닛
lenum.ally = 아군 유닛
lenum.attacker = 무기를 가진 유닛
lenum.enemy = 적 유닛
lenum.boss = 수호자 유닛
lenum.flying = 공중 유닛
lenum.ground = 지상 유닛
lenum.player = 플레이어에 의해 조종된 유닛
lenum.ore = 광석 매장지
lenum.damaged = 손상된 아군 건물
lenum.spawn = 적 스폰 지점\n코어 또는 지점일 수 있음.
lenum.building = 특정 건물 집단에 속한 건물
lenum.core = 코어
lenum.storage = 창고같은 저장 건물
lenum.generator = 전력을 생산하는 건물
lenum.factory = 자원을 변환하는 건물
lenum.repair = 수리 지점
lenum.rally = 지휘소
lenum.battery = 배터리
lenum.resupply = 보급 지점.\n[accent]"유닛 탄약 필요"[]가 활성화되었을 때만 유의미합니다.
lenum.reactor = 핵융합로/토륨 원자로
lenum.turret = 포탑ㅁ
sensor.in = 감지할 건물/유닛
radar.from = 감지를 할 건물\n감지 범위는 건물의 감지 범위에 의해 제한됩니다.
radar.target = 유닛 감지 필터
radar.and = 추가 필터
radar.order = 정렬 순서. 0은 반전
radar.sort = 결과를 정렬할 측정 수단
radar.output = 찾은 유닛을 대입할 변수
unitradar.target = 유닛 감지 필터
unitradar.and = 추가 필터
unitradar.order = 정렬 순서. 0은 반전
unitradar.sort = 결과를 정렬할 측정 수단
unitradar.output = 찾은 유닛을 대입할 변수
control.of = 조종할 건물
control.unit = 조준할 유닛/건물
control.shoot = 발사 여부
unitlocate.enemy = 적 건물 포함 여부
unitlocate.found = 대상 발견 여부
unitlocate.building = 찾은 건물을 대입할 변수
unitlocate.outx = X좌표
unitlocate.outy = Y좌표
unitlocate.group = 찾을 건물 집단
lenum.stop = 이동/채광/건설 중단
lenum.move = 특정 위치로 이동
lenum.approach = 특정 위치로 반지름만큼 접근
lenum.pathfind = 적 스폰 지점으로 길찾기
lenum.target = 특정 위치에 발사
lenum.targetp = 목표물 속도를 예측하여 발사
lenum.itemdrop = 아이템 투하
lenum.itemtake = 건물에서 아이템 수송
lenum.paydrop = 현재 화물 투하
lenum.paytake = 현재 위치에서 화물 수송
lenum.flag = 깃발 수 설정
lenum.mine = 특정 위치에서 채광
lenum.build = 구조물 건설
lenum.getblock = 특정 좌표의 빌딩과 블록을 반환합니다.\n위치는 유닛의 인지 범위 내여야 합니다.\n자연 지형은 [accent]@solid[]의 타입을 가집니다.
lenum.within = 좌표 주변 유닛 발견 여부
lenum.boost = 이륙 시작/중단

View File

@@ -11,7 +11,7 @@ link.trello.description = Oficjalna tablica Trello z planowanym funkcjami
link.itch.io.description = Strona itch.io z oficjanymi wersjami do pobrania link.itch.io.description = Strona itch.io z oficjanymi wersjami do pobrania
link.google-play.description = Strona w sklepie Google Play link.google-play.description = Strona w sklepie Google Play
link.f-droid.description = Wykaz Katalogu F-Droid link.f-droid.description = Wykaz Katalogu F-Droid
link.wiki.description = Oficjana Wiki Mindustry link.wiki.description = Oficjalna Wiki Mindustry
link.suggestions.description = Zaproponuj nowe funkcje link.suggestions.description = Zaproponuj nowe funkcje
link.bug.description = Znalazłeś błąd? Zgłoś go tutaj link.bug.description = Znalazłeś błąd? Zgłoś go tutaj
linkfail = Nie udało się otworzyć linku!\nURL został skopiowany. linkfail = Nie udało się otworzyć linku!\nURL został skopiowany.
@@ -1277,7 +1277,7 @@ hint.placeTurret = Postaw \uf861 [accent]Działka[] by bronić się przed wrogam
hint.breaking = Użyj [accent]Prawego przycisku myszy[] i przeciągnij by zniszczyć bloki. hint.breaking = Użyj [accent]Prawego przycisku myszy[] i przeciągnij by zniszczyć bloki.
hint.breaking.mobile = Aktywuj \ue817 [accent]ikonę młota[] w dolnym prawym rogu by zniszczyć bloki.\n\nPrzytrymaj swój palec i przeciągij by wybrać wiele bloków do zniszczenia. hint.breaking.mobile = Aktywuj \ue817 [accent]ikonę młota[] w dolnym prawym rogu by zniszczyć bloki.\n\nPrzytrymaj swój palec i przeciągij by wybrać wiele bloków do zniszczenia.
hint.research = Klikij przycisk \ue875 [accent]Badań[] by odkrwyać nowe technologie. hint.research = Klikij przycisk \ue875 [accent]Badań[] by odkrwyać nowe technologie.
hint.research.mobile = Użyj przycisku \ue875 [accent]Badań[] w \ue88c [accent]Menu[] by odkrwyać nowe technologie. hint.research.mobile = Użyj przycisku \ue875 [accent]Badań[] w \ue88c [accent]Menu[] by odkrywać nowe technologie.
hint.unitControl = Przytrzymaj [accent][[Lewy CTRL][] i [accent]kliknij[] by kontrolować sojusznicze jednostki i działka. hint.unitControl = Przytrzymaj [accent][[Lewy CTRL][] i [accent]kliknij[] by kontrolować sojusznicze jednostki i działka.
hint.unitControl.mobile = [accent][Kliknij dwukrotnie[] by kontrolować sojusznicze jednostki i działka. hint.unitControl.mobile = [accent][Kliknij dwukrotnie[] by kontrolować sojusznicze jednostki i działka.
hint.launch = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] wybierając \ue827 [accent]Mapę[] w dolnym prawym rogu. hint.launch = Gdy zebrałeś wystarczająco materiałów możesz [accent]Wystrzelić[] wybierając \ue827 [accent]Mapę[] w dolnym prawym rogu.
@@ -1290,10 +1290,10 @@ hint.command = Kliknij [accent][[G][] by ukształtować formacje z pobliskich je
hint.command.mobile = [accent][[Podwójne kliknięcie][] kształtuje formacje z pobliskich jednostek. hint.command.mobile = [accent][[Podwójne kliknięcie][] kształtuje formacje z pobliskich jednostek.
hint.payloadPickup = Kliknij [accent][[[] by podnieść małe bloki lub jednostki. hint.payloadPickup = Kliknij [accent][[[] by podnieść małe bloki lub jednostki.
hint.payloadPickup.mobile = [accent]Kliknij i przytrzymaj[] mały blok by go podnieść. hint.payloadPickup.mobile = [accent]Kliknij i przytrzymaj[] mały blok by go podnieść.
hint.payloadDrop = Kliknij [accent]][] by opuścić podniesoiny towar. hint.payloadDrop = Kliknij [accent]][] by opuścić podniesiony towar.
hint.payloadDrop.mobile = [accent]Kliknij i przytrzymaj[] w puste miejsce by opuścić podniesoiny towar. hint.payloadDrop.mobile = [accent]Kliknij i przytrzymaj[] w puste miejsce by opuścić podniesiony towar.
hint.waveFire = [accent]Strumień[] wypełniony wodą będzie gasić pobiskie pożary. hint.waveFire = [accent]Strumień[] wypełniony wodą będzie gasić pobiskie pożary.
hint.generator = \uf879 [accent]Generatory Spalinowe[] spalają węgiel i przekuzują moc do pobliskich bloków.\n\nMożesz powiększyć odległość transmitowanej mocy używająć \uf87f [accent]Węzły Prądu[]. hint.generator = \uf879 [accent]Generatory Spalinowe[] spalają węgiel i przekazują moc do pobliskich bloków.\n\nMożesz powiększyć odległość transmitowanej mocy używająć \uf87f [accent]Węzły Prądu[].
hint.guardian = Jednostki [accent]Strażnicze[] są uzbrojone. Słaba amunicja - taka jak [accent]Miedź[] oraz [accent]Ołów[] [scarlet]nie jest efektywna[].\n\nUżyj lepszych działek takich jak \uf835 [accent]Naładowane Grafitem[] \uf861Duo/\uf859Salwa by pozbyć się strażników. hint.guardian = Jednostki [accent]Strażnicze[] są uzbrojone. Słaba amunicja - taka jak [accent]Miedź[] oraz [accent]Ołów[] [scarlet]nie jest efektywna[].\n\nUżyj lepszych działek takich jak \uf835 [accent]Naładowane Grafitem[] \uf861Duo/\uf859Salwa by pozbyć się strażników.
hint.coreUpgrade = Rdzenie mogą być ulepszone poprzez [accent]płożenie na nich rdzeń wyższego poziomu[].\n\nPołóż  rdzeń [accent]Fundacji[] na  rdzeń:[accent]Odłamek[] core. Żadna przeszkoda ani blok nie może stać na miejscu rdzenia. hint.coreUpgrade = Rdzenie mogą być ulepszone poprzez [accent]płożenie na nich rdzeń wyższego poziomu[].\n\nPołóż  rdzeń [accent]Fundacji[] na  rdzeń:[accent]Odłamek[] core. Żadna przeszkoda ani blok nie może stać na miejscu rdzenia.
hint.presetLaunch = Szare [accent]sektory[], takie jak [accent]Zamrożony Las[], to sektory do których możesz dotrzeć z każdego miejsca. Nie wymagają podbicia pobliskiego terenu.\n\n[accent]Ponumerowane sektory[], takie jak ten, [accent]są dodatkowe[]. hint.presetLaunch = Szare [accent]sektory[], takie jak [accent]Zamrożony Las[], to sektory do których możesz dotrzeć z każdego miejsca. Nie wymagają podbicia pobliskiego terenu.\n\n[accent]Ponumerowane sektory[], takie jak ten, [accent]są dodatkowe[].
@@ -1357,8 +1357,8 @@ block.copper-wall.description = Tani blok obronny.\nPrzydatny do ochrony rdzenia
block.copper-wall-large.description = Tani blok obronny.\nPrzydatny do ochrony rdzenia i wieżyczek w pierwszych kilku falach.\nObejmuje wiele kratek. block.copper-wall-large.description = Tani blok obronny.\nPrzydatny do ochrony rdzenia i wieżyczek w pierwszych kilku falach.\nObejmuje wiele kratek.
block.titanium-wall.description = Umiarkowanie silny blok obronny.\nZapewnia umiarkowaną ochronę przed wrogami. block.titanium-wall.description = Umiarkowanie silny blok obronny.\nZapewnia umiarkowaną ochronę przed wrogami.
block.titanium-wall-large.description = Umiarkowanie silny blok obronny.\nZapewnia umiarkowaną ochronę przed wrogami.\nObejmuje wiele kratek. block.titanium-wall-large.description = Umiarkowanie silny blok obronny.\nZapewnia umiarkowaną ochronę przed wrogami.\nObejmuje wiele kratek.
block.plastanium-wall.description = Specjajny typ ściany, który pochłania łuki elektryczne oraz blokuje automatyczne łączenie węzłów. block.plastanium-wall.description = Specjalny typ ściany, który pochłania łuki elektryczne oraz blokuje automatyczne łączenie węzłów.
block.plastanium-wall-large.description = Specjajny typ ściany, który pochłania łuki elektryczne oraz blokuje automatyczne łączenie węzłów.\nObejmuje wiele kratek. block.plastanium-wall-large.description = Specjalny typ ściany, który pochłania łuki elektryczne oraz blokuje automatyczne łączenie węzłów.\nObejmuje wiele kratek.
block.thorium-wall.description = Silny blok obronny.\nDobra ochrona przed wrogami. block.thorium-wall.description = Silny blok obronny.\nDobra ochrona przed wrogami.
block.thorium-wall-large.description = Silny blok obronny.\nDobra ochrona przed wrogami.\nObejmuje wiele kratek. block.thorium-wall-large.description = Silny blok obronny.\nDobra ochrona przed wrogami.\nObejmuje wiele kratek.
block.phase-wall.description = Ściana pokryta specjalną mieszanką opartą o Włókna Fazowe, która odbija większość pocisków. block.phase-wall.description = Ściana pokryta specjalną mieszanką opartą o Włókna Fazowe, która odbija większość pocisków.

View File

@@ -41,11 +41,13 @@ be.ignore = Ignoră
be.noupdates = Niciun update disponibil. be.noupdates = Niciun update disponibil.
be.check = Verifică updateurile be.check = Verifică updateurile
mod.featured.title = Mod browser mods.browser = Browser de Moduri
mod.featured.dialog.title = Mod Browser (Neterminat)
mods.browser.selected = Mod selectat mods.browser.selected = Mod selectat
mods.browser.add = Instalează mods.browser.add = Instalare
mods.github.open = Vezi mods.browser.reinstall = Reinstal.
mods.github.open = Github
mods.browser.sortdate = Cele mai recente
mods.browser.sortstars = Cele mai multe stele
schematic = Schemă schematic = Schemă
schematic.add = Salvează Schema... schematic.add = Salvează Schema...
@@ -117,8 +119,10 @@ mods.none = [lightgray]Nu s-au găsit moduri!
mods.guide = Ghid de Modding mods.guide = Ghid de Modding
mods.report = Raportează Bug mods.report = Raportează Bug
mods.openfolder = Deschide Folder mods.openfolder = Deschide Folder
mods.viewcontent = Vezi Conținut
mods.reload = Reîncarcă mods.reload = Reîncarcă
mods.reloadexit = Jocul se va opri ca să reîncarce modurile. mods.reloadexit = Jocul se va opri ca să reîncarce modurile.
mod.installed = [[Instalat]
mod.display = [gray]Mod:[orange] {0} mod.display = [gray]Mod:[orange] {0}
mod.enabled = [lightgray]Activat mod.enabled = [lightgray]Activat
mod.disabled = [scarlet]Dezactivat mod.disabled = [scarlet]Dezactivat
@@ -308,6 +312,7 @@ cancelbuilding = [accent][[{0}][] pt a curăța planul
selectschematic = [accent][[{0}][] pt selectare+copiere selectschematic = [accent][[{0}][] pt selectare+copiere
pausebuilding = [accent][[{0}][] pt a face o pauză de la construit pausebuilding = [accent][[{0}][] pt a face o pauză de la construit
resumebuilding = [scarlet][[{0}][] pt a continua construitul resumebuilding = [scarlet][[{0}][] pt a continua construitul
enablebuilding = [scarlet][[{0}][] pt a construi
showui = Interfață ascunsă.\nApasă [accent][[{0}][] pt a vedea interfața. showui = Interfață ascunsă.\nApasă [accent][[{0}][] pt a vedea interfața.
wave = [accent]Valul {0} wave = [accent]Valul {0}
wave.cap = [accent]Valul {0}/{1} wave.cap = [accent]Valul {0}/{1}
@@ -679,6 +684,7 @@ stat.drillspeed = Viteză Burghiu (Bază)
stat.boosteffect = Efect de Îmbunătățire stat.boosteffect = Efect de Îmbunătățire
stat.maxunits = Maxim Unități Active stat.maxunits = Maxim Unități Active
stat.health = Viață stat.health = Viață
stat.armor = Armură
stat.buildtime = Timp Construcție stat.buildtime = Timp Construcție
stat.maxconsecutive = Maxim Consecutive stat.maxconsecutive = Maxim Consecutive
stat.buildcost = Cost Construcție stat.buildcost = Cost Construcție
@@ -697,6 +703,7 @@ stat.radioactivity = Radioactivitate
stat.heatcapacity = Capacitate de Căldură stat.heatcapacity = Capacitate de Căldură
stat.viscosity = Vâscozitate stat.viscosity = Vâscozitate
stat.temperature = Temperatură stat.temperature = Temperatură
stat.charge = Sarcină Electrică
stat.speed = Viteză stat.speed = Viteză
stat.buildspeed = Viteză Construcție stat.buildspeed = Viteză Construcție
stat.minespeed = Viteză Minare stat.minespeed = Viteză Minare
@@ -789,6 +796,7 @@ setting.shadows.name = Umbre
setting.blockreplace.name = Sugestii Plasare Automats setting.blockreplace.name = Sugestii Plasare Automats
setting.linear.name = Filtrare Liniară setting.linear.name = Filtrare Liniară
setting.hints.name = Indicii setting.hints.name = Indicii
setting.logichints.name = Indicii Procesoare Logice
setting.flow.name = Afișează Rata de Curgere a lichidelor setting.flow.name = Afișează Rata de Curgere a lichidelor
setting.buildautopause.name = Autopauză de la Construit setting.buildautopause.name = Autopauză de la Construit
setting.backgroundpause.name = Pune Pauză în Fundal setting.backgroundpause.name = Pune Pauză în Fundal
@@ -949,6 +957,8 @@ rules.blockdamagemultiplier = Multiplicatorul Deteriorării Blocurilor
rules.unitbuildspeedmultiplier = Multiplicatorul Vitezei de Producere a Unităților rules.unitbuildspeedmultiplier = Multiplicatorul Vitezei de Producere a Unităților
rules.unithealthmultiplier = Multiplicatorul Vieții Unităților rules.unithealthmultiplier = Multiplicatorul Vieții Unităților
rules.unitdamagemultiplier = Multiplicatorul Deteriorării Unităților rules.unitdamagemultiplier = Multiplicatorul Deteriorării Unităților
rules.unitcapvariable = Nucleele Contribuie la Limita Unităților
rules.unitcap = Limita de Bază a Unităților
rules.enemycorebuildradius = Interzisă Construirea în Jurul Nucleului Inamic:[lightgray] (pătrate) rules.enemycorebuildradius = Interzisă Construirea în Jurul Nucleului Inamic:[lightgray] (pătrate)
rules.wavespacing = Spațiul Dintre Valuri:[lightgray] (sec) rules.wavespacing = Spațiul Dintre Valuri:[lightgray] (sec)
rules.buildcostmultiplier = Multiplicatorul Costului Construcției rules.buildcostmultiplier = Multiplicatorul Costului Construcției
@@ -1139,10 +1149,6 @@ block.armored-conveyor.name = Bandă Armată
block.junction.name = Intersecție block.junction.name = Intersecție
block.router.name = Router block.router.name = Router
block.distributor.name = Distributor block.distributor.name = Distributor
#experimental, pot fi șterse în viitor
block.block-forge.name = Forjă de Blocuri
block.block-loader.name = Încărcător de Blocuri
block.block-unloader.name = Descărcător de Blocuri
block.sorter.name = Sortator block.sorter.name = Sortator
block.inverted-sorter.name = Sortator Invers block.inverted-sorter.name = Sortator Invers
block.message.name = Mesaj block.message.name = Mesaj
@@ -1243,6 +1249,10 @@ block.disassembler.name = Dezasamblator
block.silicon-crucible.name = Creuzet de Silicon block.silicon-crucible.name = Creuzet de Silicon
block.overdrive-dome.name = Dom de Suprasolicitare block.overdrive-dome.name = Dom de Suprasolicitare
block.interplanetary-accelerator.name = Accelerator Interplanetar block.interplanetary-accelerator.name = Accelerator Interplanetar
#experimental, pot fi șterse în viitor
block.block-forge.name = Forjă de Blocuri
block.block-loader.name = Încărcător de Blocuri
block.block-unloader.name = Descărcător de Blocuri
block.switch.name = Întrerupător block.switch.name = Întrerupător
block.micro-processor.name = Microprocesor block.micro-processor.name = Microprocesor
@@ -1384,8 +1394,8 @@ block.inverted-sorter.description = Similar sortatorului standard, dar materialu
block.router.description = Distribuie materialele primite în alte 3 direcții în mod egal. block.router.description = Distribuie materialele primite în alte 3 direcții în mod egal.
block.router.details = Un rău necesar. Nu folosi niciodată pt a introduce materiale în blocuri, căci vor fi blocate de produșii blocurilor. block.router.details = Un rău necesar. Nu folosi niciodată pt a introduce materiale în blocuri, căci vor fi blocate de produșii blocurilor.
block.distributor.description = Distribuie materialele primite în alte 7 direcții în mod egal. block.distributor.description = Distribuie materialele primite în alte 7 direcții în mod egal.
block.overflow-gate.description = Transportă materialele doar la stânga și dreapta dacă drumul din față este blocat. Nu poate fi folosită lângă alte porți. block.overflow-gate.description = Transportă materialele doar la stânga și dreapta dacă drumul din față este blocat.
block.underflow-gate.description = Opusul porții de revărsare. Transportă materialele în față dacă benzile din stânga și dreapta sunt blocate. Nu poate fi folosită lângă alte porți. block.underflow-gate.description = Opusul porții de revărsare. Transportă materialele în față dacă benzile din stânga și dreapta sunt blocate.
block.mass-driver.description = Dispozitiv folosit pt transportul materialelor pe distanțe mari. Adună mai multe materiale și apoi le lansează până la un alt distributor în masă pe o rază mare. block.mass-driver.description = Dispozitiv folosit pt transportul materialelor pe distanțe mari. Adună mai multe materiale și apoi le lansează până la un alt distributor în masă pe o rază mare.
block.mechanical-pump.description = Pompează lichide din mediul înconjurător. Nu necesită electricitate. block.mechanical-pump.description = Pompează lichide din mediul înconjurător. Nu necesită electricitate.
block.rotary-pump.description = Pompează lichide din mediul înconjurător. Necesită electricitate. block.rotary-pump.description = Pompează lichide din mediul înconjurător. Necesită electricitate.
@@ -1445,6 +1455,7 @@ block.ripple.description = Lovește cu capsule către inamici pe distanțe mari.
block.cyclone.description = Trage cu grămezi explozive de material către unitățile inamice din apropiere. block.cyclone.description = Trage cu grămezi explozive de material către unitățile inamice din apropiere.
block.spectre.description = Trage cu gloanțe mari care penetrează scuturile inamicilor din apropiere. block.spectre.description = Trage cu gloanțe mari care penetrează scuturile inamicilor din apropiere.
block.meltdown.description = Se încarcă și trage cu un laser continuu la inamicii din apropiere. Necesită răcitor pt a opera. block.meltdown.description = Se încarcă și trage cu un laser continuu la inamicii din apropiere. Necesită răcitor pt a opera.
block.foreshadow.description = Trage către o țintă cu un glonț imens pe distanțe lungi.
block.repair-point.description = Repară încontinuu cea mai deteriorată unitate din vecinătate. block.repair-point.description = Repară încontinuu cea mai deteriorată unitate din vecinătate.
block.segment.description = Deteriorează și distruge proiectilele din apropiere. Laserele nu sunt afectate. block.segment.description = Deteriorează și distruge proiectilele din apropiere. Laserele nu sunt afectate.
block.parallax.description = Trage cu o rază tractoare care atrage aeronavele inamice, deteriorându-le. block.parallax.description = Trage cu o rază tractoare care atrage aeronavele inamice, deteriorându-le.
@@ -1505,3 +1516,127 @@ unit.omura.description = Trage cu un railgun cu gloanțe care penetrează scutur
unit.alpha.description = Apără nucleul Shard de inamici. Construiește structuri. unit.alpha.description = Apără nucleul Shard de inamici. Construiește structuri.
unit.beta.description = Apără nucleul Foundation de inamici. Construiește structuri. unit.beta.description = Apără nucleul Foundation de inamici. Construiește structuri.
unit.gamma.description = Apără nucleul Core de inamici. Construiește structuri. unit.gamma.description = Apără nucleul Core de inamici. Construiește structuri.
lst.read = Citește un număr dintr-o celulă de memorie conectată.
lst.write = Scrie un număr într-o celulă de memorie conectată.
lst.print = Adaugă text în bufferul de tipărire.\nNu tipărește decât când se execută [accent]Print Flush[].
lst.draw = Adaugă o operație în bufferul de desenare.\nNu afișează decât când se execută [accent]Draw Flush[].
lst.drawflush = Afișează pe un monitor instrucțiunile [accent]Draw[] aflate în așteptare.
lst.printflush = Tipărește într-un bloc Mesaj instrucțiunile [accent]Print[] aflate în așteptare.
lst.getlink = Obține o conexiune a procesorului după index. Începe de la 0.
lst.control = Controlează o clădire.
lst.radar = Localizează unitățile aflate în jurul unei clădiri. Are o anumită rază de acțiune.
lst.sensor = Obține date de la o clădire sau unitate.
lst.set = Setează o variabilă.
lst.operation = Efectuează o operație pe 1-2 variabile.
lst.end = Sari la începutul listei de instrucțiuni.
lst.jump = Dacă condiția este adevărată, mergi la o altă instrucțiune.
lst.unitbind = Controlează următoarea unitate de tipul selectat și reține-o în [accent]@unit[].
lst.unitcontrol = Controlează unitatea controlată de procesor.
lst.unitradar = Localizează unitățile din jurul unității controlate de procesor.
lst.unitlocate = Localizează o poziție/clădire specifică oriunde pe hartă.\nNecesită o unitate controlată de procesor.
lenum.type = Tipul clădirii/unității.\nde ex.: pt orice Router, va returna [accent]@router[].\nNu e un șir de caractere.
lenum.shoot = Lovește către o locație.
lenum.shootp = Lovește către o unitate/clădire. Anticipează viteza țintei și a proiectilului.
lenum.configure = Configurașia clădirii, de ex. materialul selectat pt Sortator.
lenum.enabled = Specifică dacă clădirea este pornită.
lenum.color = Culoarea Iluminatorului.
lenum.always = Mereu adevărat.
lenum.idiv = Împărțirea naturală a numerelor (int).
lenum.div = Împărțirea.\nReturnează [accent]null[] dacă împarți la 0.
lenum.mod = Modulo (restul împărțirii).
lenum.equal = Egal. Convertește tipurile variabilelor.\nObiectele nenule comparate cu numere devin 1, cele nule devin 0.
lenum.notequal = Nu e egal. Convertește tipurile variabilelor.
lenum.strictequal = Egalitate strictă. Nu convertește tipurile variabilelor.\nPoate fi folosit pt a verifica dacă ceva este [accent]null[].
lenum.shl = Shift left pe biți.
lenum.shr = Shift right pe biți.
lenum.or = OR/SAU. Ține cont de biți.
lenum.land = Logical AND/ȘI logic. Nu ține cont de biți.
lenum.and = AND/ȘI. Ține cont de biți.
lenum.not = NOT. Inversează biții.
lenum.xor = XOR/disjuncție exclusivă. Ține cont de biți.
lenum.min = Minimul a două numere.
lenum.max = Maximul a două numere.
lenum.angle = Unghiul unui vector în grade.
lenum.len = Lungimea unui vector.
lenum.sin = Sinus în grade.
lenum.cos = Cosinus în grade.
lenum.tan = Tangentă în grade.
#cea de mai jos nu-i o greșeală, caută pe net notarea intervalelor în matematică
lenum.rand = Număr aleatoriu în intervalul [0, val).
lenum.log = Logaritm natural (ln).
lenum.log10 = Logaritm în baza 10.
lenum.noise = 2D simplex noise.
lenum.abs = Valoarea absolută.
lenum.sqrt = Radical/rădăcina pătrată.
lenum.any = Orice unitate.
lenum.ally = Unitate aliată.
lenum.attacker = Unitate cu armă.
lenum.enemy = Unitate inamică.
lenum.boss = Unitate gardian.
lenum.flying = Unitate care zboară.
lenum.ground = Unitate de artilerie.
lenum.player = Unitate controlată de un jucător.
lenum.ore = Depozit de minereu.
lenum.damaged = Clădire aliată deteriorată.
lenum.spawn = Punct de lansare inamic.\nPoate fi un nucleu sau o poziție.
lenum.building = Clădire dintr-un grup specific.
lenum.core = Orice nucleu.
lenum.storage = Clădire de stocare, de ex. Containerul.
lenum.generator = Clădiri care generează electricitate.
lenum.factory = Clădiri care transformă resurse.
lenum.repair = Puncte de Reparare.
lenum.rally = Centre de Comandă.
lenum.battery = Orice baterie.
lenum.resupply = Puncte de Realimentare.\nRelevant doar când [accent]"Unitățile Necesită Muniție"[] este activată.
lenum.reactor = Reactor de Toriu/Impact.
lenum.turret = Orice armă.
sensor.in = Clădirea/unitatea care trebuie detectată.
radar.from = Clădirea de la care detectăm.\nRaza senzorului e limitată de raza de costrucție.
radar.target = Filtru pt unitățile care trebuie detectate.
radar.and = Adaugă filtre.
radar.order = Ordinea de sortare. 0 pt a inversa ordinea.
radar.sort = Modul cum sortăm rezultatele.
radar.output = Variabila în care se va scrie unitatea detectată.
unitradar.target = Filtru pt unitățile care trebuie detectate.
unitradar.and = Adaugă filtre.
unitradar.order = Ordinea de sortare. 0 pt a inversa ordinea.
unitradar.sort = Modul cum sortăm rezultatele.
unitradar.output = Variabila în care se reține unitatea detectată.
control.of = Clădirea de controlat.
control.unit = Unitatea/clădirea către care se țintește.
control.shoot = Specifică dacă armele trag.
unitlocate.enemy = Specifică dacă se detectează clădirile inamice.
unitlocate.found = Specifică dacă obiectul a fost găsit.
unitlocate.building = Clădirea detectată.
unitlocate.outx = Coordonata X a obiectului detectat.
unitlocate.outy = Coordonata Y a obiectului detectat.
unitlocate.group = Grupul clădirilor de detectat.
lenum.stop = Oprește acțiunea curentă. Nu mișca/mina/construi.
lenum.move = Mergi la această poziție.
lenum.approach = Apropie-te la o anumită distanță de poziție.
lenum.pathfind = Găsește ruta către punctul de lansare inamic. Poate fi un nucleu.
lenum.target = Lovește către o poziție.
lenum.targetp = Lovește o țintă. Anticipează viteza țintei și a proiectilului.
lenum.itemdrop = Descarcă o bucată de material.
lenum.itemtake = Ia o bucată de material dintr-o clădire.
lenum.paydrop = Descarcă încărcătura curentă.
lenum.paytake = Ia o încărcătură de la locația curentă.
lenum.flag = Oferă o etichetă numerică unității.
lenum.mine = Minează din această locație.
lenum.build = Construiește o structură.
lenum.getblock = Obține clădirea și tipul clădirii aflate la coordonatele specificate.\nUnitatea trebuie să se afle în raza poziției.\nBlocurile solide care nu sunt clădiri vor avea tipul [accent]@solid[].
lenum.within = Verifică dacă unitatea se află în apropierea poziției.
lenum.boost = Pornește/oprește propulsorul.

View File

@@ -41,10 +41,13 @@ be.ignore = Игнорировать
be.noupdates = Обновления не найдены. be.noupdates = Обновления не найдены.
be.check = Проверить обновления be.check = Проверить обновления
mod.featured.dialog.title = Браузер модификаций mods.browser = Браузер\nмодификаций
mods.browser.selected = Выбранный мод mods.browser.selected = Выбранный мод
mods.browser.add = Скачать mods.browser.add = Скачать
mods.github.open = Открыть mods.browser.reinstall = Переустановить
mods.github.open = Сайт
mods.browser.sortdate = Сортировка по дате
mods.browser.sortstars = Сортировка по звёздам
schematic = Схема schematic = Схема
schematic.add = Сохранить схему… schematic.add = Сохранить схему…
@@ -116,8 +119,10 @@ mods.none = [lightgray]Модификации не найдены!
mods.guide = Руководство по модификациям mods.guide = Руководство по модификациям
mods.report = Доложить об ошибке mods.report = Доложить об ошибке
mods.openfolder = Открыть папку с модификациями mods.openfolder = Открыть папку с модификациями
mods.viewcontent = Просмотреть содержимое
mods.reload = Перезагрузить mods.reload = Перезагрузить
mods.reloadexit = Игра будет закрыта для перезагрузки модификаций. mods.reloadexit = Игра будет закрыта для перезагрузки модификаций.
mod.installed = [[Установлено]
mod.display = [gray]Модификация:[orange] {0} mod.display = [gray]Модификация:[orange] {0}
mod.enabled = [lightgray]Включён mod.enabled = [lightgray]Включён
mod.disabled = [scarlet]Выключен mod.disabled = [scarlet]Выключен
@@ -307,6 +312,7 @@ cancelbuilding = [accent][[{0}][] для очистки плана
selectschematic = [accent][[{0}][] выделить и скопировать selectschematic = [accent][[{0}][] выделить и скопировать
pausebuilding = [accent][[{0}][] для приостановки строительства pausebuilding = [accent][[{0}][] для приостановки строительства
resumebuilding = [scarlet][[{0}][] для продолжения строительства resumebuilding = [scarlet][[{0}][] для продолжения строительства
enablebuilding = [scarlet][[{0}][] для включения строительства
showui = Интерфейс скрыт.\nНажмите [accent][[{0}][] для отображения интерфейса. showui = Интерфейс скрыт.\nНажмите [accent][[{0}][] для отображения интерфейса.
wave = [accent]Волна {0} wave = [accent]Волна {0}
wave.cap = [accent]Волна {0}/{1} wave.cap = [accent]Волна {0}/{1}
@@ -678,6 +684,7 @@ stat.drillspeed = Базовая скорость бурения
stat.boosteffect = Ускоряющий эффект stat.boosteffect = Ускоряющий эффект
stat.maxunits = Максимальное количество активных единиц stat.maxunits = Максимальное количество активных единиц
stat.health = Прочность stat.health = Прочность
stat.armor = Броня
stat.buildtime = Время строительства stat.buildtime = Время строительства
stat.maxconsecutive = Макс. последовательность stat.maxconsecutive = Макс. последовательность
stat.buildcost = Стоимость строительства stat.buildcost = Стоимость строительства
@@ -693,6 +700,7 @@ stat.lightningchance = Шанс удара молнии
stat.lightningdamage = Урон молнии stat.lightningdamage = Урон молнии
stat.flammability = Воспламеняемость stat.flammability = Воспламеняемость
stat.radioactivity = Радиоактивность stat.radioactivity = Радиоактивность
stat.charge = Заряд
stat.heatcapacity = Теплоёмкость stat.heatcapacity = Теплоёмкость
stat.viscosity = Вязкость stat.viscosity = Вязкость
stat.temperature = Температура stat.temperature = Температура
@@ -788,6 +796,7 @@ setting.shadows.name = Тени
setting.blockreplace.name = Автоматическая замена блоков setting.blockreplace.name = Автоматическая замена блоков
setting.linear.name = Линейная фильтрация setting.linear.name = Линейная фильтрация
setting.hints.name = Подсказки setting.hints.name = Подсказки
setting.logichints.name = Подсказки для логики
setting.flow.name = Показывать скорость потока ресурсов setting.flow.name = Показывать скорость потока ресурсов
setting.backgroundpause.name = Фоновая пауза setting.backgroundpause.name = Фоновая пауза
setting.buildautopause.name = Автоматическая приостановка строительства setting.buildautopause.name = Автоматическая приостановка строительства
@@ -1383,8 +1392,8 @@ block.inverted-sorter.description = Работает так же, как и ст
block.router.description = Равномерно распределяет входящие предметы по 3 выходящим направлениям. block.router.description = Равномерно распределяет входящие предметы по 3 выходящим направлениям.
block.router.details = Необходимое зло. Не рекомендуется к использованию как блок ввода возле производственных зданий, т.к. может случиться затор выходным материалом. block.router.details = Необходимое зло. Не рекомендуется к использованию как блок ввода возле производственных зданий, т.к. может случиться затор выходным материалом.
block.distributor.description = Равномерно распределяет входящие предметы по 7 выходящим направлениям. block.distributor.description = Равномерно распределяет входящие предметы по 7 выходящим направлениям.
block.overflow-gate.description = Выводит предметы по бокам, только если передний путь заблокирован. Нельзя использовать вплотную к другим затворам или шлюзам. block.overflow-gate.description = Выводит предметы по бокам, только если передний путь заблокирован.
block.underflow-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 = Перекачивает и выводит жидкости. Требует энергию.
@@ -1497,11 +1506,135 @@ unit.poly.description = Автоматически восстанавливае
unit.mega.description = Автоматически ремонтирует повреждённые постройки. Может переносить блоки и небольшие единицы. unit.mega.description = Автоматически ремонтирует повреждённые постройки. Может переносить блоки и небольшие единицы.
unit.quad.description = Сбрасывает большие бомбы на наземные цели, восстанавливая союзные постройки и повреждая врагов. Может переносить единицы среднего размера. unit.quad.description = Сбрасывает большие бомбы на наземные цели, восстанавливая союзные постройки и повреждая врагов. Может переносить единицы среднего размера.
unit.oct.description = Защищает союзников поблизости при помощи своего восстанавливающегося щита. Может переносить большинство наземных единиц. unit.oct.description = Защищает союзников поблизости при помощи своего восстанавливающегося щита. Может переносить большинство наземных единиц.
unit.risso.description = Стреляет залпом ракет и пуль по всем врагам поблизости. unit.risso.description = Стреляет залпами ракет и пуль по всем врагам поблизости.
unit.minke.description = Стреляет зажигательными снарядами и стандартными пулями по наземным целям. unit.minke.description = Стреляет зажигательными снарядами и стандартными пулями по наземным целям.
unit.bryde.description = Стреляет дальнобойными артиллерийскими снарядами и ракетами по врагам. unit.bryde.description = Стреляет дальнобойными артиллерийскими снарядами и ракетами по врагам.
unit.sei.description = Стреляет залпом ракет и бронебойных пуль по врагам. unit.sei.description = Стреляет залпами ракет и бронебойных пуль по врагам.
unit.omura.description = Стреляет дальнобойным пробивающим снарядом из рельсотрона по врагам. Производит единицы «Вспышка». unit.omura.description = Стреляет дальнобойным пробивающим снарядом из рельсотрона по врагам. Производит единицы «Вспышка».
unit.alpha.description = Защищает ядро «Осколок» от врагов. Основная строительная единица. unit.alpha.description = Защищает ядро «Осколок» от врагов. Основная строительная единица.
unit.beta.description = Защищает ядро «Штаб» от врагов. Основная строительная единица. unit.beta.description = Защищает ядро «Штаб» от врагов. Основная строительная единица.
unit.gamma.description = Защищает ядро «Атом» от врагов. Основная строительная единица. unit.gamma.description = Защищает ядро «Атом» от врагов. Основная строительная единица.
lst.read = Считывает число из соединённой ячейки памяти.
lst.write = Записывает число в соединённую ячейку памяти.
lst.print = Добавляет текст в текстовый буфер. Ничего не отображает, пока не будет вызван [accent]Print Flush[].
lst.draw = Добавляет операцию в буфер отрисовки. Ничего не отображает, пока не будет вызван [accent]Draw Flush[].
lst.drawflush = Сбрасывает буфер [accent]Draw[] операций на дисплей.
lst.printflush = Сбрасывает буфер [accent]Print[] операций в блок-сообщение.
lst.getlink = Получает соединение процессора по индексу. Начинает с 0.
lst.control = Контролирует блок.
lst.radar = Обнаруживает единицы вокруг постройки с заданным радиусом.
lst.sensor = Получает данные из постройки или единицы.
lst.set = Устанавливает переменную.
lst.operation = Совершает операцию над 1-2 переменными.
lst.end = Переходит к началу стека операций.
lst.jump = Условно переходит к другой операции.
lst.unitbind = Привязывается к единице определённого типа и сохраняет её в [accent]@unit[].
lst.unitcontrol = Управляет привязанной в данный момент единицей.
lst.unitradar = Обнаруживает единицы вокруг привязанной в данный момент единицы.
lst.unitlocate = Обнаруживает позицию/постройку определённого типа где-либо на карте. Требует привязанную единицу.
lenum.type = Тип постройки/единицы. \nНапример, для маршрутизатора это будет [accent]@router[].\nНе строка.
lenum.shoot = Стрельба в определённую позицию.
lenum.shootp = Стрельба в единицу/постройку с расчётом скорости.
lenum.configure = Конфигурация постройки, например, предмет сортировки.
lenum.enabled = Включён ли блок.
lenum.color = Цвет осветителя.
lenum.always = Всегда истина.
lenum.idiv = Целочисленное деление.
lenum.div = Деление.\nВозвращает [accent]null[] при делении на ноль.
lenum.mod = Остаток от деления.
lenum.equal = Равно. Приводит типы.\nНе-null объекты, по сравнению с числами, становятся 1, иначе — 0.
lenum.notequal = Не равно. Приводит типы.
lenum.strictequal = Строгое равенство. Не приводит типы.\nМожет быть использовано для проверки на [accent]null[].
lenum.shl = Побитовый сдвиг влево.
lenum.shr = Побитовый сдвиг вправо.
lenum.or = Побитовое ИЛИ.
lenum.land = Булевое И.
lenum.and = Побитовое И.
lenum.not = Побитовое НЕ.
lenum.xor = Побитовое исключающее ИЛИ.
lenum.min = Минимальное из двух чисел.
lenum.max = Максимальное из двух чисел.
lenum.angle = Угол вектора в градусах.
lenum.len = Длина вектора.
lenum.sin = Синус, в градусах.
lenum.cos = Косинус, в градусах.
lenum.tan = Тангенс, в градусах.
#это не ошибка, поищите 'обозначение диапазонов'
lenum.rand = Случайное число в диапазоне [0, значение).
lenum.log = Натуральный логарифм (ln).
lenum.log10 = Логарифм по основанию 10.
lenum.noise = Симплексный шум, 2D.
lenum.abs = Абсолютная величина.
lenum.sqrt = Квадратный корень.
lenum.any = Любая единица.
lenum.ally = Дружеская единица.
lenum.attacker = Единица с оружием.
lenum.enemy = Вражеская единица.
lenum.boss = Страж.
lenum.flying = Летающая единица.
lenum.ground = Наземная единица.
lenum.player = Единица, управляемая игроком.
lenum.ore = Источник руды.
lenum.damaged = Повреждённая дружеская постройка.
lenum.spawn = Точка появления врагов.\nМожет быть ядром или позицией на карте.
lenum.building = Постройка определённой группы.
lenum.core = Любое ядро.
lenum.storage = Здание хранения, например, хранилище.
lenum.generator = Постройки, вырабатывающие энергию.
lenum.factory = Постройки, перерабатывающие предметы.
lenum.repair = Ремонтные пункты.
lenum.rally = Командный центр.
lenum.battery = Любой аккумулятор.
lenum.resupply = Пункты снабжения.\nАктуально только при включённом [accent]"Боев. ед. требуют боеприпасы"[].
lenum.reactor = Импульсный/ториевый реактор.
lenum.turret = Любая турель.
sensor.in = Постройка/единица для распознавания.
radar.from = Постройка, от которой распознавать.\nДальность сенсора ограничена дальностью постройки.
radar.target = Фильтр для распознавания единиц.
radar.and = Дополнительные фильтры.
radar.order = Порядок сортировки. 0 для обратного.
radar.sort = Показатель для сортировки результатов.
radar.output = Переменная для записи конечной единицы.
unitradar.target = Фильтр для распознавания единиц.
unitradar.and = Дополнительные фильтры.
unitradar.order = Порядок сортировки. 0 для обратного.
unitradar.sort = Показатель для сортировки результатов.
unitradar.output = Переменная для записи конечной единицы.
control.of = Постройка для контролирования.
control.unit = Единица/постройка для прицеливания.
control.shoot = Стрелять ли.
unitlocate.enemy = Обнаруживать ли вражеские постройки.
unitlocate.found = Найден ли объект.
unitlocate.building = Переменная для записи обнаруженной постройки.
unitlocate.outx = Вывод X координаты.
unitlocate.outy = Вывод Y координаты.
unitlocate.group = Группа построек для поиска.
lenum.stop = Остановка передвижения/копания/стротельства.
lenum.move = Перемещение в определённую позицию.
lenum.approach = Приближение к позиции с указанным радиусом.
lenum.pathfind = Перемещение к точке появления врагов.
lenum.target = Стрельба в определённую позицию.
lenum.targetp = Стрельба в единицу/постройку с расчётом скорости.
lenum.itemdrop = Сбрасывание предметов.
lenum.itemtake = Взятие предметов из постройки.
lenum.paydrop = Сбрасывание текущего груза.
lenum.paytake = Взятие груза на текущей позиции.
lenum.flag = Числовой флаг единицы.
lenum.mine = Копание в позиции.
lenum.build = Строительство структур.
lenum.getblock = Распознавание блока и его типа на координатах.\nЕдиница должна находиться в пределах досягаемости.\nТвёрдые не-постройки будут иметь тип [accent]@solid[].
lenum.within = Проверка на нахождение единицы рядом с позицией.
lenum.boost = Включение/выключение полёта.

View File

@@ -59,8 +59,10 @@ schematic.disabled = [scarlet]Схеми вимкнені[]\nВам не доз
mod.featured.title = Переглядач модифікацій mod.featured.title = Переглядач модифікацій
mod.featured.dialog.title = Переглядач модифікацій mod.featured.dialog.title = Переглядач модифікацій
mods.browser.selected = Обрана модифікація mods.browser.selected = Обрана модифікація
mods.browser.add = Установити модифікацію mods.browser.add = Установити
mods.github.open = Відкрити в Github mods.github.open = Відкрити
mods.browser.sortdate = Сортувати за давністю
mods.browser.sortstars = Сортувати за кількостю зірок
stats = Статистика stats = Статистика
stat.wave = Хвиль відбито:[accent] {0} stat.wave = Хвиль відбито:[accent] {0}
@@ -85,6 +87,7 @@ joingame = Мережева гра
customgame = Користувацька гра customgame = Користувацька гра
newgame = Нова гра newgame = Нова гра
none = <нічого> none = <нічого>
none.found = [lightgray]<нічого не знайдено>
minimap = Мінімапа minimap = Мінімапа
position = Місцезнаходження position = Місцезнаходження
close = Закрити close = Закрити
@@ -278,6 +281,7 @@ cancel = Скасувати
openlink = Перейти за посиланням openlink = Перейти за посиланням
copylink = Скопіювати посилання copylink = Скопіювати посилання
back = Назад back = Назад
max = Макс.
crash.export = Експортувати аварійні звіти crash.export = Експортувати аварійні звіти
crash.none = Аварійних звітів не знайдено crash.none = Аварійних звітів не знайдено
crash.exported = Аварійні звіти експортовано crash.exported = Аварійні звіти експортовано
@@ -351,7 +355,6 @@ editor.center = Центрувати
workshop = Майстерня workshop = Майстерня
waves.title = Хвилі waves.title = Хвилі
waves.remove = Видалити waves.remove = Видалити
waves.never = <ніколи>
waves.every = кожен waves.every = кожен
waves.waves = хвиля(і) waves.waves = хвиля(і)
waves.perspawn = за появу waves.perspawn = за появу
@@ -377,7 +380,7 @@ editor.removeunit = Видалити бойову одиницю
editor.teams = Команди editor.teams = Команди
editor.errorload = Помилка завантаження зображення. editor.errorload = Помилка завантаження зображення.
editor.errorsave = Помилка збереження зображення. editor.errorsave = Помилка збереження зображення.
editor.errorimage = Це зображення, а не мапа.\n\nЯкщо ви хочете імпортувати застарілу мапу, то використовуйте кнопку «Імпортувати застарілу мапу» в редакторі. editor.errorimage = Це зображення, а не мапа.
editor.errorlegacy = Ця мапа занадто стара і використовує попередній формат мапи, який більше не підтримується. editor.errorlegacy = Ця мапа занадто стара і використовує попередній формат мапи, який більше не підтримується.
editor.errornot = Це не мапа. editor.errornot = Це не мапа.
editor.errorheader = Цей файл мапи недійсний або пошкоджений. editor.errorheader = Цей файл мапи недійсний або пошкоджений.
@@ -676,6 +679,7 @@ stat.commandlimit = Максимум у загоні
stat.abilities = Здібності stat.abilities = Здібності
stat.canboost = Можна прискорити stat.canboost = Можна прискорити
stat.flying = Літає stat.flying = Літає
stat.ammouse = Патронів використовує
ability.forcefield = Щитове поле ability.forcefield = Щитове поле
ability.repairfield = Ремонтувальне поле ability.repairfield = Ремонтувальне поле
ability.statusfield = Поле підсилення ability.statusfield = Поле підсилення
@@ -688,6 +692,7 @@ bar.corereq = Необхідне основне ядро
bar.drillspeed = Швидкість буріння: {0} за с. bar.drillspeed = Швидкість буріння: {0} за с.
bar.pumpspeed = Швидкість викачування: {0} за с. bar.pumpspeed = Швидкість викачування: {0} за с.
bar.efficiency = Ефективність: {0}% bar.efficiency = Ефективність: {0}%
bar.boost = Підсилення: {0}%
bar.powerbalance = Енергія: {0} за с. bar.powerbalance = Енергія: {0} за с.
bar.powerstored = Зберігає: {0}/{1} bar.powerstored = Зберігає: {0}/{1}
bar.poweramount = Енергія: {0} bar.poweramount = Енергія: {0}
@@ -696,7 +701,6 @@ bar.powerlines = З’єднань: {0}/{1}
bar.items = Предмети: {0} bar.items = Предмети: {0}
bar.capacity = Місткість: {0} bar.capacity = Місткість: {0}
bar.unitcap = {0} {1}/{2} bar.unitcap = {0} {1}/{2}
bar.limitreached = [scarlet] {0} / {1}[white] {2}\n[lightgray][[одиниця вимкнена]
bar.liquid = Рідина bar.liquid = Рідина
bar.heat = Нагрівання bar.heat = Нагрівання
bar.power = Енергія bar.power = Енергія
@@ -711,6 +715,7 @@ bullet.sapping = [stat]виснажує
bullet.homing = [stat]самонаведення bullet.homing = [stat]самонаведення
bullet.shock = [stat]шок bullet.shock = [stat]шок
bullet.frag = [stat]шкода по ділянці bullet.frag = [stat]шкода по ділянці
bullet.buildingdamage = [stat]{0}%[lightgray] шкода по будівлям
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]пробиття
@@ -738,6 +743,7 @@ unit.items = предм.
unit.thousands = тис unit.thousands = тис
unit.millions = млн unit.millions = млн
unit.billions = млрд unit.billions = млрд
unit.pershot = за постріл
category.purpose = Призначення category.purpose = Призначення
category.general = Загальне category.general = Загальне
category.power = Енергія category.power = Енергія
@@ -806,6 +812,7 @@ setting.lasersopacity.name = Непрозорість лазерів енерг
setting.bridgeopacity.name = Непрозорість мостів setting.bridgeopacity.name = Непрозорість мостів
setting.playerchat.name = Показувати хмару чата над гравцями setting.playerchat.name = Показувати хмару чата над гравцями
public.confirm = Ви хочете зробити цю гру загальнодоступною?\n[accent]Будь-хто може приєднатися до вашої гри.\n[lightgray]Це можна змінити в Налаштування->Гра->Загальнодоступність гри. public.confirm = Ви хочете зробити цю гру загальнодоступною?\n[accent]Будь-хто може приєднатися до вашої гри.\n[lightgray]Це можна змінити в Налаштування->Гра->Загальнодоступність гри.
public.confirm.really = Якщо ви хочете грати з друзями, використовуйте [green]Запросити друзів[] замість [scarlet]Публічного серверу[]!\nВи справді хочете зробити свою гру [scarlet]публічною[]?
public.beta = Зауважте, що в бета-версії гри ви не можете робити публічні ігри. public.beta = Зауважте, що в бета-версії гри ви не можете робити публічні ігри.
uiscale.reset = Масштаб користувацького інтерфейсу було змінено.\nНатисніть «Гаразд» для підтвердження цього масштабу.\n[scarlet]Повернення налаштувань і вихід через[accent] {0}[] секунд… uiscale.reset = Масштаб користувацького інтерфейсу було змінено.\nНатисніть «Гаразд» для підтвердження цього масштабу.\n[scarlet]Повернення налаштувань і вихід через[accent] {0}[] секунд…
uiscale.cancel = Скасувати і вийти uiscale.cancel = Скасувати і вийти
@@ -880,6 +887,7 @@ keybind.toggle_menus.name = Меню перемикання
keybind.chat_history_prev.name = Попередня історія чату keybind.chat_history_prev.name = Попередня історія чату
keybind.chat_history_next.name = Наступна історія чату keybind.chat_history_next.name = Наступна історія чату
keybind.chat_scroll.name = Прокрутка чату keybind.chat_scroll.name = Прокрутка чату
keybind.chat_mode.name = Змінити режим чату
keybind.drop_unit.name = Скинути бойову одиницю keybind.drop_unit.name = Скинути бойову одиницю
keybind.zoom_minimap.name = Збільшити мінімапу keybind.zoom_minimap.name = Збільшити мінімапу
mode.help.title = Опис режимів гри mode.help.title = Опис режимів гри
@@ -895,6 +903,7 @@ mode.attack.description = Зруйнуйте ворожу базу. \n[gray]По
mode.custom = Користувацькі правила mode.custom = Користувацькі правила
rules.infiniteresources = Нескінченні ресурси rules.infiniteresources = Нескінченні ресурси
rules.reactorexplosions = Вибухи реактора rules.reactorexplosions = Вибухи реактора
rules.coreincinerates = Ядро спалює надлишкові предмети
rules.schematic = Використання схем дозволено rules.schematic = Використання схем дозволено
rules.wavetimer = Таймер для хвиль rules.wavetimer = Таймер для хвиль
rules.waves = Хвилі rules.waves = Хвилі

View File

@@ -41,10 +41,13 @@ be.ignore = 忽略
be.noupdates = 沒有新的更新。 be.noupdates = 沒有新的更新。
be.check = 檢查是否有新的更新 be.check = 檢查是否有新的更新
mod.featured.dialog.title = 模組瀏覽器 (尚未完成) mods.browser = 模組瀏覽器
mods.browser.selected = 已選模組 mods.browser.selected = 已選模組
mods.browser.add = 安裝 mods.browser.add = 安裝
mods.github.open = 查看 mods.github.reinstall = 重新安裝
mods.github.open = 查看Github
mods.browser.sortdate = 以最近篩選
mods.browser.sortstars = 以星數篩選
schematic = 藍圖 schematic = 藍圖
schematic.add = 儲存藍圖…… schematic.add = 儲存藍圖……
@@ -116,9 +119,11 @@ mods.none = [lightgray]找不到模組!
mods.guide = 模組指南 mods.guide = 模組指南
mods.report = 回報錯誤 mods.report = 回報錯誤
mods.openfolder = 開啟模組資料夾 mods.openfolder = 開啟模組資料夾
mods.viewcontent = 查看內容
mods.reload = 重新載入 mods.reload = 重新載入
mods.reloadexit = 遊戲將會結束以重新載入模組。 mods.reloadexit = 遊戲將會結束以重新載入模組。
mod.display = [gray]模組:[orange]{0} mod.display = [gray]模組:[orange]{0}
mod.installed = [[已安裝]
mod.enabled = [lightgray]已啟用 mod.enabled = [lightgray]已啟用
mod.disabled = [scarlet]已禁用 mod.disabled = [scarlet]已禁用
mod.disable = 禁用 mod.disable = 禁用
@@ -307,6 +312,7 @@ cancelbuilding = [accent][[{0}][]清除計畫
selectschematic = [accent][[{0}][]選擇並複製 selectschematic = [accent][[{0}][]選擇並複製
pausebuilding = [accent][[{0}][]暫停建造 pausebuilding = [accent][[{0}][]暫停建造
resumebuilding = [scarlet][[{0}][]繼續建造 resumebuilding = [scarlet][[{0}][]繼續建造
enablebuilding = [scarlet][[{0}][]啟用建造
showui = 已隱藏介面。\n按[accent][[{0}][]顯示介面。 showui = 已隱藏介面。\n按[accent][[{0}][]顯示介面。
wave = [accent]第{0}波 wave = [accent]第{0}波
wave.cap = [accent]Wave {0}/{1} wave.cap = [accent]Wave {0}/{1}
@@ -420,7 +426,7 @@ editor.exportimage = 匯出地形圖片檔
editor.exportimage.description = 匯出地形圖片檔 editor.exportimage.description = 匯出地形圖片檔
editor.loadimage = 載入圖片 editor.loadimage = 載入圖片
editor.saveimage = 儲存圖片 editor.saveimage = 儲存圖片
editor.unsaved = [scarlet]未儲存變更[]\n您確定要退出嗎 editor.unsaved = 您確定要退出嗎?\n[scarlet](將遺失未儲存變更)[]
editor.resizemap = 調整地圖大小 editor.resizemap = 調整地圖大小
editor.mapname = 地圖名稱: editor.mapname = 地圖名稱:
editor.overwrite = [accent]警告!這將會覆蓋現有的地圖。 editor.overwrite = [accent]警告!這將會覆蓋現有的地圖。
@@ -678,6 +684,7 @@ stat.drillspeed = 基本鑽取速度
stat.boosteffect = 加速效果 stat.boosteffect = 加速效果
stat.maxunits = 最大活躍單位 stat.maxunits = 最大活躍單位
stat.health = 耐久度 stat.health = 耐久度
stat.armor = 裝甲
stat.buildtime = 建設時間 stat.buildtime = 建設時間
stat.maxconsecutive = 最大連續 stat.maxconsecutive = 最大連續
stat.buildcost = 建造成本 stat.buildcost = 建造成本
@@ -693,6 +700,7 @@ stat.lightningchance = 燃燒機率
stat.lightningdamage = 燃燒傷害 stat.lightningdamage = 燃燒傷害
stat.flammability = 易燃性 stat.flammability = 易燃性
stat.radioactivity = 輻射性 stat.radioactivity = 輻射性
stat.charge = 蓄電力
stat.heatcapacity = 熱容量 stat.heatcapacity = 熱容量
stat.viscosity = 黏度 stat.viscosity = 黏度
stat.temperature = 溫度 stat.temperature = 溫度
@@ -788,6 +796,7 @@ setting.shadows.name = 陰影
setting.blockreplace.name = 方塊建造建議 setting.blockreplace.name = 方塊建造建議
setting.linear.name = 線性過濾 setting.linear.name = 線性過濾
setting.hints.name = 提示 setting.hints.name = 提示
setting.logichints.name = 邏輯提示
setting.flow.name = 顯示資源輸送速度 setting.flow.name = 顯示資源輸送速度
setting.backgroundpause.name = 背景執行時暫停 setting.backgroundpause.name = 背景執行時暫停
setting.buildautopause.name = 自動暫停建築 setting.buildautopause.name = 自動暫停建築
@@ -1505,3 +1514,127 @@ unit.omura.description = 對敵人發射遠程穿透型砲彈。建造曳光戰
unit.alpha.description = 抵禦敵軍對核心:碎片的攻擊。建造建築物。 unit.alpha.description = 抵禦敵軍對核心:碎片的攻擊。建造建築物。
unit.beta.description = 抵禦敵軍對核心:基地的攻擊。建造建築物。 unit.beta.description = 抵禦敵軍對核心:基地的攻擊。建造建築物。
unit.gamma.description = 抵禦敵軍對核心:核子的攻擊。建造建築物。 unit.gamma.description = 抵禦敵軍對核心:核子的攻擊。建造建築物。
lst.read = [accent]讀取[]記憶體中的一項數值
lst.write = [accent]寫入[]一項數值到記憶體中
lst.print = 將文字加入輸出的暫存中,搭配[accent]Print Flush[]使用
lst.draw = 將圖形加入顯示的暫存中,搭配[accent]Draw Flush[]使用
lst.drawflush = 將所有暫存的[accent]Draw[]指令推到顯示器上
lst.printflush = 將所有暫存的[accent]Print[]指令推到訊息板上
lst.getlink = 由連接順序回傳連接的建築,第一個從"0"開始
lst.control = 控制一個建築
lst.radar = 偵測建築範圍內的單位
lst.sensor = 獲取該建築或單位的數據
lst.set = 設一個變數
lst.operation = 加減乘除和計算機概論
lst.end = 跳到第一個重頭開始執行
lst.jump = 條件式跳到其他指令執行
lst.unitbind = 綁定下一同種單位,存入[accent]@unit[]中.
lst.unitcontrol = 控制現在綁定的單位
lst.unitradar = 偵測綁定單位附近的單位
lst.unitlocate = 尋找整個地圖上特定的位置/建築\n需要綁定的單位
lenum.type = 建築/單位種類。\n例操控單位建造光矛砲應使用[accent]@lancer[],而非字串
lenum.shoot = 對該位置開火
lenum.shootp = 對指定單位/建築開火,具自瞄功能
lenum.configure = 建築設定,如分類器、兵器工廠
lenum.enabled = 確認該建築是否啟用
lenum.color = 設定照明燈的顏色
lenum.always = 永遠 true (直接跳).
lenum.idiv = 整數除法,無條件捨去.
lenum.div = 除法.\n除以零時回傳 [accent]null[]
lenum.mod = Modulo求餘數
lenum.equal = 是否相等,不管資料型態。\n非null 物件和數值相比時回傳1
lenum.notequal = 不相等,不管資料型態.
lenum.strictequal = 嚴格檢查是否相等,會看資料型態。\n可用來檢查[accent]null[]
lenum.shl = Bit-shift left.
lenum.shr = Bit-shift right.
lenum.or = Bitwise OR.
lenum.land = Logical AND.
lenum.and = Bitwise AND.
lenum.not = Bitwise flip.
lenum.xor = Bitwise XOR.
lenum.min = Minimum of two numbers.
lenum.max = Maximum of two numbers.
lenum.angle = Angle of vector in degrees.
lenum.len = Length of vector.
lenum.sin = Sine, in degrees.
lenum.cos = Cosine, in degrees.
lenum.tan = Tangent, in degrees.
#not a typo, look up 'range notation'
lenum.rand = Random number in range [0, value).
lenum.log = Natural logarithm (ln).
lenum.log10 = Base 10 logarithm.
lenum.noise = 2D simplex noise.
lenum.abs = 取絕對值
lenum.sqrt = 開根號
lenum.any = 任何單位
lenum.ally = 友方單位
lenum.attacker = 具武器的單位
lenum.enemy = 敵方單位
lenum.boss = 頭目單位
lenum.flying = 飛行單位
lenum.ground = 陸上單位
lenum.player = 玩家單位
lenum.ore = 尋找礦物
lenum.damaged = 尋找受損友方建築
lenum.spawn = 敵方重生點\n可以是核心或一個位置
lenum.building = 尋找特定建築
lenum.core = 任何核心
lenum.storage = 儲藏建築
lenum.generator = 會發電的建築
lenum.factory = 生產加工資源的建築,如煉矽場
lenum.repair = 維修點
lenum.rally = 指揮中心
lenum.battery = 電池
lenum.resupply = 補給點\n只有在[accent]"單位需要彈藥"[]被啟用時才有效果
lenum.reactor = 衝擊/釷反應爐
lenum.turret = 任何砲塔
sensor.in = 想查閱的建築/單位
radar.from = 作為雷達的建築\n偵測範圍同該建築的範圍
radar.target = 搜索條件
radar.and = 額外條件
radar.order = 輸出順序1距離最近、血量最大
radar.sort = 篩選方式
radar.output = 回傳該單位為變數
unitradar.target = 搜索條件
unitradar.and = 額外條件
unitradar.order = 輸出順序1距離最近、血量最大
unitradar.sort = 篩選方式
unitradar.output = 存該單位的變數
control.of = 要控制的建築
control.unit = 指定的建築/單位
control.shoot = 是否開火
unitlocate.enemy = 搜索敵方或友方建築
unitlocate.found = 回傳是否找到建築
unitlocate.building = 回傳找到的建築為變數
unitlocate.outx = 回傳 X 座標
unitlocate.outy = 回傳 Y 座標
unitlocate.group = 搜索建築種類
lenum.stop = 停止移動/挖礦/建造
lenum.move = 移動到指定位置
lenum.approach = 移動到距離指定位置一段距離的地方
lenum.pathfind = 由內建AI前往敵方重生點
lenum.target = 射擊指定區域
lenum.targetp = 帶自瞄射擊指定的目標
lenum.itemdrop = 放下物品
lenum.itemtake = 從建築拿取物品
lenum.paydrop = 放下拾取的負載
lenum.paytake = 拾取船身下方的單位/建築
lenum.flag = 單位編號(可異)
lenum.mine = 挖指定位置的礦物
lenum.build = 建造一個建築
lenum.getblock = 獲取指定位置的建築種類和該建築\n必須在單位的範圍內\n實體障礙物如高山會回傳[accent]@solid[]
lenum.within = 單位是否在指定範圍內
lenum.boost = 使用推進器

View File

@@ -14,7 +14,6 @@
63730=magmarock|block-magmarock-medium 63730=magmarock|block-magmarock-medium
63729=sand|block-sand-medium 63729=sand|block-sand-medium
63728=darksand|block-darksand-medium 63728=darksand|block-darksand-medium
63727=holostone|block-holostone-medium
63726=grass|block-grass-medium 63726=grass|block-grass-medium
63725=salt|block-salt-medium 63725=salt|block-salt-medium
63724=snow|block-snow-medium 63724=snow|block-snow-medium
@@ -285,7 +284,6 @@
63451=scepter|unit-scepter-medium 63451=scepter|unit-scepter-medium
63450=reign|unit-reign-medium 63450=reign|unit-reign-medium
63449=dirt|block-dirt-medium 63449=dirt|block-dirt-medium
63448=dirtwall|block-dirtwall-medium
63447=stone-wall|block-stone-wall-medium 63447=stone-wall|block-stone-wall-medium
63446=spore-wall|block-spore-wall-medium 63446=spore-wall|block-spore-wall-medium
63445=ice-wall|block-ice-wall-medium 63445=ice-wall|block-ice-wall-medium
@@ -295,7 +293,6 @@
63441=salt-wall|block-salt-wall-medium 63441=salt-wall|block-salt-wall-medium
63440=shale-wall|block-shale-wall-medium 63440=shale-wall|block-shale-wall-medium
63439=dirt-wall|block-dirt-wall-medium 63439=dirt-wall|block-dirt-wall-medium
63438=holostone-wall|block-holostone-wall-medium
63437=basalt|block-basalt-medium 63437=basalt|block-basalt-medium
63436=dacite|block-dacite-medium 63436=dacite|block-dacite-medium
63435=boulder|block-boulder-medium 63435=boulder|block-boulder-medium

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -133,6 +133,7 @@ const PlayerLeave = Packages.mindustry.game.EventType.PlayerLeave
const PlayerConnect = Packages.mindustry.game.EventType.PlayerConnect const PlayerConnect = Packages.mindustry.game.EventType.PlayerConnect
const PlayerJoin = Packages.mindustry.game.EventType.PlayerJoin const PlayerJoin = Packages.mindustry.game.EventType.PlayerJoin
const UnitChangeEvent = Packages.mindustry.game.EventType.UnitChangeEvent const UnitChangeEvent = Packages.mindustry.game.EventType.UnitChangeEvent
const UnitUnloadEvent = Packages.mindustry.game.EventType.UnitUnloadEvent
const UnitCreateEvent = Packages.mindustry.game.EventType.UnitCreateEvent const UnitCreateEvent = Packages.mindustry.game.EventType.UnitCreateEvent
const UnitDrownEvent = Packages.mindustry.game.EventType.UnitDrownEvent const UnitDrownEvent = Packages.mindustry.game.EventType.UnitDrownEvent
const UnitDestroyEvent = Packages.mindustry.game.EventType.UnitDestroyEvent const UnitDestroyEvent = Packages.mindustry.game.EventType.UnitDestroyEvent
@@ -161,6 +162,7 @@ const LaunchItemEvent = Packages.mindustry.game.EventType.LaunchItemEvent
const SectorInvasionEvent = Packages.mindustry.game.EventType.SectorInvasionEvent const SectorInvasionEvent = Packages.mindustry.game.EventType.SectorInvasionEvent
const SectorLoseEvent = Packages.mindustry.game.EventType.SectorLoseEvent const SectorLoseEvent = Packages.mindustry.game.EventType.SectorLoseEvent
const WorldLoadEvent = Packages.mindustry.game.EventType.WorldLoadEvent const WorldLoadEvent = Packages.mindustry.game.EventType.WorldLoadEvent
const FileTreeInitEvent = Packages.mindustry.game.EventType.FileTreeInitEvent
const ClientLoadEvent = Packages.mindustry.game.EventType.ClientLoadEvent const ClientLoadEvent = Packages.mindustry.game.EventType.ClientLoadEvent
const ContentInitEvent = Packages.mindustry.game.EventType.ContentInitEvent const ContentInitEvent = Packages.mindustry.game.EventType.ContentInitEvent
const BlockInfoEvent = Packages.mindustry.game.EventType.BlockInfoEvent const BlockInfoEvent = Packages.mindustry.game.EventType.BlockInfoEvent

Binary file not shown.

View File

@@ -38,6 +38,8 @@ public class Vars implements Loadable{
public static boolean loadedLogger = false, loadedFileLogger = false; public static boolean loadedLogger = false, loadedFileLogger = false;
/** Whether to enable various experimental features (e.g. cliffs) */ /** Whether to enable various experimental features (e.g. cliffs) */
public static boolean experimental = false; public static boolean experimental = false;
/** Name of current Steam player. */
public static String steamPlayerName = "";
/** Maximum extra padding around deployment schematics. */ /** Maximum extra padding around deployment schematics. */
public static final int maxLoadoutSchematicPad = 5; public static final int maxLoadoutSchematicPad = 5;
/** Maximum schematic size.*/ /** Maximum schematic size.*/
@@ -50,20 +52,18 @@ public class Vars implements Loadable{
public static final Charset charset = Charset.forName("UTF-8"); public static final Charset charset = Charset.forName("UTF-8");
/** main application name, capitalized */ /** main application name, capitalized */
public static final String appName = "Mindustry"; public static final String appName = "Mindustry";
/** URL for itch.io donations. */ /** Github API URL. */
public static final String donationURL = "https://anuke.itch.io/mindustry/purchase"; public static final String ghApi = "https://api.github.com";
/** URL for discord invite. */ /** URL for discord invite. */
public static final String discordURL = "https://discord.gg/mindustry"; public static final String discordURL = "https://discord.gg/mindustry";
/** URL for sending crash reports to */ /** URL for sending crash reports to. Currently offline. */
public static final String crashReportURL = "http://192.99.169.18/report"; public static final String crashReportURL = "http://192.99.169.18/report";
/** URL the links to the wiki's modding guide.*/ /** URL the links to the wiki's modding guide.*/
public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/"; public static final String modGuideURL = "https://mindustrygame.github.io/wiki/modding/1-modding/";
/** URL to the JSON file containing all the global, public servers. Not queried in BE. */
public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers.json";
/** URL to the JSON file containing all the BE servers. Only queried in BE. */ /** URL to the JSON file containing all the BE servers. Only queried in BE. */
public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json"; public static final String serverJsonBeURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_be.json";
/** URL to the JSON file containing all the BE servers. Only queried in the V6 alpha (will be removed once it's out). */ /** URL to the JSON file containing all the BE servers. */
public static final String serverJsonV6URL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json"; public static final String serverJsonURL = "https://raw.githubusercontent.com/Anuken/Mindustry/master/servers_v6.json";
/** URL of the github issue report template.*/ /** URL of the github issue report template.*/
public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md"; public static final String reportIssueURL = "https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md";
/** list of built-in servers.*/ /** list of built-in servers.*/
@@ -345,7 +345,7 @@ public class Vars implements Loadable{
} }
public static void loadSettings(){ public static void loadSettings(){
settings.setJson(JsonIO.json()); settings.setJson(JsonIO.json);
settings.setAppName(appName); settings.setAppName(appName);
if(steam || (Version.modifier != null && Version.modifier.contains("steam"))){ if(steam || (Version.modifier != null && Version.modifier.contains("steam"))){

View File

@@ -269,7 +269,6 @@ public class BlockIndexer{
public Building findTile(Team team, float x, float y, float range, Boolf<Building> pred, boolean usePriority){ public Building findTile(Team team, float x, float y, float range, Boolf<Building> pred, boolean usePriority){
Building closest = null; Building closest = null;
float dst = 0; float dst = 0;
float range2 = range * range;
for(int rx = Math.max((int)((x - range) / tilesize / quadrantSize), 0); rx <= (int)((x + range) / tilesize / quadrantSize) && rx < quadWidth(); rx++){ for(int rx = Math.max((int)((x - range) / tilesize / quadrantSize), 0); rx <= (int)((x + range) / tilesize / quadrantSize) && rx < quadWidth(); rx++){
for(int ry = Math.max((int)((y - range) / tilesize / quadrantSize), 0); ry <= (int)((y + range) / tilesize / quadrantSize) && ry < quadHeight(); ry++){ for(int ry = Math.max((int)((y - range) / tilesize / quadrantSize), 0); ry <= (int)((y + range) / tilesize / quadrantSize) && ry < quadHeight(); ry++){
@@ -282,13 +281,13 @@ public class BlockIndexer{
if(e == null || e.team != team || !pred.get(e) || !e.block.targetable || e.team == Team.derelict) continue; if(e == null || e.team != team || !pred.get(e) || !e.block.targetable || e.team == Team.derelict) continue;
float ndst = e.dst2(x, y); float bdst = e.dst(x, y) - e.hitSize() / 2f;
if(ndst < range2 && (closest == null || if(bdst < range && (closest == null ||
//this one is closer, and it is at least of equal priority //this one is closer, and it is at least of equal priority
(ndst < dst && (!usePriority || closest.block.priority.ordinal() <= e.block.priority.ordinal())) || (bdst < dst && (!usePriority || closest.block.priority.ordinal() <= e.block.priority.ordinal())) ||
//priority is used, and new block has higher priority regardless of range //priority is used, and new block has higher priority regardless of range
(usePriority && closest.block.priority.ordinal() < e.block.priority.ordinal()))){ (usePriority && closest.block.priority.ordinal() < e.block.priority.ordinal()))){
dst = ndst; dst = bdst;
closest = e; closest = e;
} }
} }

View File

@@ -23,7 +23,6 @@ public class Pathfinder implements Runnable{
private static final int updateFPS = 60; private static final int updateFPS = 60;
private static final int updateInterval = 1000 / updateFPS; private static final int updateInterval = 1000 / updateFPS;
private static final int impassable = -1; private static final int impassable = -1;
private static final int fieldTimeout = 1000 * 60 * 2;
public static final int public static final int
fieldCore = 0, fieldCore = 0,
@@ -192,31 +191,6 @@ public class Pathfinder implements Runnable{
//total update time no longer than maxUpdate //total update time no longer than maxUpdate
for(Flowfield data : threadList){ for(Flowfield data : threadList){
updateFrontier(data, maxUpdate / threadList.size); updateFrontier(data, maxUpdate / threadList.size);
//TODO implement timeouts... or don't
/*
//remove flowfields that have 'timed out' so they can be garbage collected and no longer waste space
if(data.refreshRate > 0 && Time.timeSinceMillis(data.lastUpdateTime) > fieldTimeout){
//make sure it doesn't get removed twice
data.lastUpdateTime = Time.millis();
Team team = data.team;
Core.app.post(() -> {
//remove its used state
if(fieldMap[team.id] != null){
fieldMap[team.id].remove(data.target);
fieldMapUsed[team.id].remove(data.target);
}
//remove from main thread list
mainList.remove(data);
});
queue.post(() -> {
//remove from this thread list with a delay
threadList.remove(data);
});
}*/
} }
} }

View File

@@ -73,7 +73,7 @@ public class WaveSpawner{
for(int i = 0; i < spawned; i++){ for(int i = 0; i < spawned; i++){
Unit unit = group.createUnit(state.rules.waveTeam, state.wave - 1); Unit unit = group.createUnit(state.rules.waveTeam, state.wave - 1);
unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread)); unit.set(spawnX + Mathf.range(spread), spawnY + Mathf.range(spread));
unit.add(); spawnEffect(unit);
} }
}); });
}else{ }else{
@@ -92,7 +92,7 @@ public class WaveSpawner{
} }
} }
Time.runTask(121f, () -> spawning = false); Time.run(121f, () -> spawning = false);
} }
public void doShockwave(float x, float y){ public void doShockwave(float x, float y){
@@ -148,8 +148,7 @@ public class WaveSpawner{
private void eachFlyerSpawn(Floatc2 cons){ private void eachFlyerSpawn(Floatc2 cons){
for(Tile tile : spawns){ for(Tile tile : spawns){
float angle = Angles.angle(world.width() / 2, world.height() / 2, tile.x, tile.y); float angle = Angles.angle(world.width() / 2f, world.height() / 2f, tile.x, tile.y);
float trns = Math.max(world.width(), world.height()) * Mathf.sqrt2 * tilesize; float trns = Math.max(world.width(), world.height()) * Mathf.sqrt2 * tilesize;
float spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(angle, trns), -margin, world.width() * tilesize + margin); float spawnX = Mathf.clamp(world.width() * tilesize / 2f + Angles.trnsx(angle, trns), -margin, world.width() * tilesize + margin);
float spawnY = Mathf.clamp(world.height() * tilesize / 2f + Angles.trnsy(angle, trns), -margin, world.height() * tilesize + margin); float spawnY = Mathf.clamp(world.height() * tilesize / 2f + Angles.trnsy(angle, trns), -margin, world.height() * tilesize + margin);
@@ -168,6 +167,7 @@ public class WaveSpawner{
} }
private void reset(){ private void reset(){
spawning = false;
spawns.clear(); spawns.clear();
for(Tile tile : world.tiles){ for(Tile tile : world.tiles){
@@ -178,8 +178,11 @@ public class WaveSpawner{
} }
private void spawnEffect(Unit unit){ private void spawnEffect(Unit unit){
Call.spawnEffect(unit.x, unit.y, unit.type); unit.rotation = unit.angleTo(world.width()/2f * tilesize, world.height()/2f * tilesize);
Time.run(30f, unit::add); unit.apply(StatusEffects.unmoving, 30f);
unit.add();
Call.spawnEffect(unit.x, unit.y, unit.rotation, unit.type);
} }
private interface SpawnConsumer{ private interface SpawnConsumer{
@@ -187,8 +190,8 @@ public class WaveSpawner{
} }
@Remote(called = Loc.server, unreliable = true) @Remote(called = Loc.server, unreliable = true)
public static void spawnEffect(float x, float y, UnitType type){ public static void spawnEffect(float x, float y, float rotation, UnitType u){
Fx.unitSpawn.at(x, y, 0f, type); Fx.unitSpawn.at(x, y, rotation, u);
Time.run(30f, () -> Fx.spawn.at(x, y)); Time.run(30f, () -> Fx.spawn.at(x, y));
} }

View File

@@ -13,9 +13,12 @@ import mindustry.world.blocks.ConstructBlock.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class BuilderAI extends AIController{ public class BuilderAI extends AIController{
float buildRadius = 1500; public static float buildRadius = 1500, retreatDst = 110f, fleeRange = 370f, retreatDelay = Time.toSeconds * 2f;
boolean found = false; boolean found = false;
@Nullable Unit following; @Nullable Unit following;
@Nullable Teamc enemy;
float retreatTimer;
@Override @Override
public void updateMovement(){ public void updateMovement(){
@@ -27,6 +30,7 @@ public class BuilderAI extends AIController{
unit.updateBuilding = true; unit.updateBuilding = true;
if(following != null){ if(following != null){
retreatTimer = 0f;
//try to follow and mimic someone //try to follow and mimic someone
//validate follower //validate follower
@@ -39,9 +43,25 @@ public class BuilderAI extends AIController{
//set to follower's first build plan, whatever that is //set to follower's first build plan, whatever that is
unit.plans.clear(); unit.plans.clear();
unit.plans.addFirst(following.buildPlan()); unit.plans.addFirst(following.buildPlan());
}else if(unit.buildPlan() == null){
//not following anyone or building
if(timer.get(timerTarget4, 40)){
enemy = target(unit.x, unit.y, fleeRange, true, true);
}
//fly away from enemy when not doing anything, but only after a delay
if((retreatTimer += Time.delta) >= retreatDelay){
if(enemy != null){
var core = unit.closestCore();
if(core != null && !unit.within(core, retreatDst)){
moveTo(core, retreatDst);
}
}
}
} }
if(unit.buildPlan() != null){ if(unit.buildPlan() != null){
retreatTimer = 0f;
//approach request if building //approach request if building
BuildPlan req = unit.buildPlan(); BuildPlan req = unit.buildPlan();

View File

@@ -128,6 +128,9 @@ public class LogicAI extends AIController{
vec.setZero(); vec.setZero();
} }
//do not move when infinite vectors are used.
if(vec.isNaN() || vec.isInfinite()) return;
unit.approach(vec); unit.approach(vec);
} }

View File

@@ -1,11 +1,16 @@
package mindustry.ai.types; package mindustry.ai.types;
import arc.util.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.world.blocks.ConstructBlock.*; import mindustry.world.blocks.ConstructBlock.*;
public class RepairAI extends AIController{ public class RepairAI extends AIController{
public static float retreatDst = 160f, fleeRange = 310f, retreatDelay = Time.toSeconds * 3f;
@Nullable Teamc avoid;
float retreatTimer;
@Override @Override
protected void updateMovement(){ protected void updateMovement(){
@@ -29,6 +34,25 @@ public class RepairAI extends AIController{
unit.lookAt(target); unit.lookAt(target);
} }
//not repairing
if(!(target instanceof Building)){
if(timer.get(timerTarget4, 40)){
avoid = target(unit.x, unit.y, fleeRange, true, true);
}
if((retreatTimer += Time.delta) >= retreatDelay){
//fly away from enemy when not doing anything
if(avoid != null){
var core = unit.closestCore();
if(core != null && !unit.within(core, retreatDst)){
moveTo(core, retreatDst);
}
}
}
}else{
retreatTimer = 0f;
}
} }
@Override @Override

View File

@@ -1,5 +1,6 @@
package mindustry.ai.types; package mindustry.ai.types;
import arc.math.geom.*;
import mindustry.*; import mindustry.*;
import mindustry.ai.*; import mindustry.ai.*;
import mindustry.entities.*; import mindustry.entities.*;
@@ -47,7 +48,8 @@ public class SuicideAI extends GroundAI{
//raycast for target //raycast for target
boolean blocked = Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> { boolean blocked = Vars.world.raycast(unit.tileX(), unit.tileY(), target.tileX(), target.tileY(), (x, y) -> {
Tile tile = Vars.world.tile(x, y); for(Point2 p : Geometry.d4c){
Tile tile = Vars.world.tile(x + p.x, y + p.y);
if(tile != null && tile.build == target) return false; if(tile != null && tile.build == target) return false;
if(tile != null && tile.build != null && tile.build.team != unit.team()){ if(tile != null && tile.build != null && tile.build.team != unit.team()){
blockedByBlock = true; blockedByBlock = true;
@@ -55,6 +57,8 @@ public class SuicideAI extends GroundAI{
}else{ }else{
return tile == null || tile.solid(); return tile == null || tile.solid();
} }
}
return false;
}); });
//shoot when there's an enemy block in the way //shoot when there's an enemy block in the way

View File

@@ -37,8 +37,9 @@ public class PhysicsProcess implements AsyncProcess{
//find Unit without bodies and assign them //find Unit without bodies and assign them
for(Unit entity : group){ for(Unit entity : group){
if(entity.type == null) continue;
if(entity.physref() == null){ if(entity.physref == null){
PhysicsBody body = new PhysicsBody(); PhysicsBody body = new PhysicsBody();
body.x = entity.x(); body.x = entity.x();
body.y = entity.y(); body.y = entity.y();
@@ -48,13 +49,13 @@ public class PhysicsProcess implements AsyncProcess{
PhysicRef ref = new PhysicRef(entity, body); PhysicRef ref = new PhysicRef(entity, body);
refs.add(ref); refs.add(ref);
entity.physref(ref); entity.physref = ref;
physics.add(body); physics.add(body);
} }
//save last position //save last position
PhysicRef ref = entity.physref(); PhysicRef ref = entity.physref;
ref.body.layer = ref.body.layer =
entity.type.allowLegStep ? layerLegs : entity.type.allowLegStep ? layerLegs :

View File

@@ -1,8 +1,6 @@
package mindustry.content; package mindustry.content;
import arc.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.struct.*; import arc.struct.*;
import mindustry.*; import mindustry.*;
import mindustry.ctype.*; import mindustry.ctype.*;
@@ -97,36 +95,9 @@ public class Blocks implements ContentList{
public void load(){ public void load(){
//region environment //region environment
air = new Floor("air"){ air = new AirBlock("air");
{
alwaysReplace = true;
hasShadow = false;
useColor = false;
wall = this;
}
@Override public void drawBase(Tile tile){} spawn = new SpawnBlock("spawn");
@Override public void load(){}
@Override public void init(){}
@Override public boolean isHidden(){ return true; }
@Override
public TextureRegion[] variantRegions(){
if(variantRegions == null){
variantRegions = new TextureRegion[]{Core.atlas.find("clear")};
}
return variantRegions;
}
};
spawn = new OverlayFloor("spawn"){
{
variants = 0;
needsSurface = false;
}
@Override
public void drawBase(Tile tile){}
};
cliff = new Cliff("cliff"){{ cliff = new Cliff("cliff"){{
inEditor = false; inEditor = false;
@@ -788,6 +759,7 @@ public class Blocks implements ContentList{
health = 130 * wallHealthMultiplier; health = 130 * wallHealthMultiplier;
insulated = true; insulated = true;
absorbLasers = true; absorbLasers = true;
schematicPriority = 10;
}}; }};
plastaniumWallLarge = new Wall("plastanium-wall-large"){{ plastaniumWallLarge = new Wall("plastanium-wall-large"){{
@@ -796,6 +768,7 @@ public class Blocks implements ContentList{
size = 2; size = 2;
insulated = true; insulated = true;
absorbLasers = true; absorbLasers = true;
schematicPriority = 10;
}}; }};
thoriumWall = new Wall("thorium-wall"){{ thoriumWall = new Wall("thorium-wall"){{
@@ -1398,6 +1371,7 @@ public class Blocks implements ContentList{
size = 3; size = 3;
itemCapacity = 1000; itemCapacity = 1000;
flags = EnumSet.of(BlockFlag.storage); flags = EnumSet.of(BlockFlag.storage);
group = BlockGroup.transportation;
}}; }};
container = new StorageBlock("container"){{ container = new StorageBlock("container"){{
@@ -1405,6 +1379,7 @@ public class Blocks implements ContentList{
size = 2; size = 2;
itemCapacity = 300; itemCapacity = 300;
flags = EnumSet.of(BlockFlag.storage); flags = EnumSet.of(BlockFlag.storage);
group = BlockGroup.transportation;
}}; }};
unloader = new Unloader("unloader"){{ unloader = new Unloader("unloader"){{
@@ -1661,6 +1636,7 @@ public class Blocks implements ContentList{
shootEffect = Fx.shootLiquid; shootEffect = Fx.shootLiquid;
range = 190f; range = 190f;
health = 250 * size * size; health = 250 * size * size;
flags = EnumSet.of(BlockFlag.turret, BlockFlag.extinguisher);
}}; }};
fuse = new ItemTurret("fuse"){{ fuse = new ItemTurret("fuse"){{
@@ -2071,6 +2047,7 @@ public class Blocks implements ContentList{
hasPower = true; hasPower = true;
consumes.power(10f); consumes.power(10f);
buildCostMultiplier = 0.5f; buildCostMultiplier = 0.5f;
health = size * size * 80;
}}; }};
//endregion campaign //endregion campaign

View File

@@ -26,17 +26,23 @@ public class Fx{
none = new Effect(0, 0f, e -> {}), none = new Effect(0, 0f, e -> {}),
unitSpawn = new Effect(30f, e -> { unitSpawn = new Effect(30f, e -> {
if(!(e.data instanceof UnitType)) return; if(!(e.data instanceof UnitType unit)) return;
alpha(e.fin());
float scl = 1f + e.fout() * 2f; float scl = 1f + e.fout() * 2f;
UnitType unit = e.data();
TextureRegion region = unit.icon(Cicon.full); TextureRegion region = unit.icon(Cicon.full);
alpha(e.fout());
mixcol(Color.white, e.fin());
rect(region, e.x, e.y, 180f);
reset();
alpha(e.fin());
rect(region, e.x, e.y, rect(region, e.x, e.y,
region.width * Draw.scl * scl, region.height * Draw.scl * scl, 180f); region.width * Draw.scl * scl, region.height * Draw.scl * scl, e.rotation - 90);
}), }),
@@ -718,6 +724,19 @@ public class Fx{
Lines.circle(e.x, e.y, 5f * e.fout()); Lines.circle(e.x, e.y, 5f * e.fout());
}), }),
forceShrink = new Effect(20, e -> {
color(e.color, e.fout());
if(renderer.animateShields){
Fill.poly(e.x, e.y, 6, e.rotation * e.fout());
}else{
stroke(1.5f);
Draw.alpha(0.09f);
Fill.poly(e.x, e.y, 6, e.rotation * e.fout());
Draw.alpha(1f);
Lines.poly(e.x, e.y, 6, e.rotation * e.fout());
}
}).layer(Layer.shields),
flakExplosionBig = new Effect(30, e -> { flakExplosionBig = new Effect(30, e -> {
color(Pal.bulletYellowBack); color(Pal.bulletYellowBack);
@@ -1590,6 +1609,12 @@ public class Fx{
Fill.square(e.x, e.y, e.rotation * tilesize / 2f); Fill.square(e.x, e.y, e.rotation * tilesize / 2f);
}), }),
lightBlock = new Effect(60, e -> {
color(e.color);
alpha(e.fout() * 1);
Fill.square(e.x, e.y, e.rotation * tilesize / 2f);
}),
overdriveBlockFull = new Effect(60, e -> { overdriveBlockFull = new Effect(60, e -> {
color(e.color); color(e.color);
alpha(e.fslope() * 0.4f); alpha(e.fslope() * 0.4f);

View File

@@ -74,6 +74,7 @@ public class Items implements ContentList{
surgeAlloy = new Item("surge-alloy", Color.valueOf("f3e979")){{ surgeAlloy = new Item("surge-alloy", Color.valueOf("f3e979")){{
cost = 1.2f; cost = 1.2f;
charge = 0.75f;
}}; }};
sporePod = new Item("spore-pod", Color.valueOf("7457ce")){{ sporePod = new Item("spore-pod", Color.valueOf("7457ce")){{

View File

@@ -21,7 +21,7 @@ public class StatusEffects implements ContentList{
burning = new StatusEffect("burning"){{ burning = new StatusEffect("burning"){{
color = Pal.lightFlame; color = Pal.lightFlame;
damage = 0.12f; //over 8 seconds, this would be 60 damage damage = 0.12f; //over 8 seconds, this would be ~60 damage
effect = Fx.burning; effect = Fx.burning;
init(() -> { init(() -> {
@@ -29,7 +29,7 @@ public class StatusEffects implements ContentList{
trans(tarred, ((unit, time, newTime, result) -> { trans(tarred, ((unit, time, newTime, result) -> {
unit.damagePierce(8f); unit.damagePierce(8f);
Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f)); Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f));
result.set(this, Math.min(time + newTime, 300f)); result.set(burning, Math.min(time + newTime, 300f));
})); }));
}); });
}}; }};
@@ -45,7 +45,7 @@ public class StatusEffects implements ContentList{
trans(blasted, ((unit, time, newTime, result) -> { trans(blasted, ((unit, time, newTime, result) -> {
unit.damagePierce(18f); unit.damagePierce(18f);
result.set(this, time); result.set(freezing, time);
})); }));
}); });
}}; }};
@@ -72,7 +72,7 @@ public class StatusEffects implements ContentList{
if(unit.team == state.rules.waveTeam){ if(unit.team == state.rules.waveTeam){
Events.fire(Trigger.shock); Events.fire(Trigger.shock);
} }
result.set(this, time); result.set(wet, time);
})); }));
opposite(burning); opposite(burning);
}); });
@@ -97,7 +97,7 @@ public class StatusEffects implements ContentList{
trans(tarred, ((unit, time, newTime, result) -> { trans(tarred, ((unit, time, newTime, result) -> {
unit.damagePierce(8f); unit.damagePierce(8f);
Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f)); Fx.burning.at(unit.x + Mathf.range(unit.bounds() / 2f), unit.y + Mathf.range(unit.bounds() / 2f));
result.set(this, Math.min(time + newTime, 200f)); result.set(melting, Math.min(time + newTime, 200f));
})); }));
}); });
}}; }};
@@ -161,10 +161,12 @@ public class StatusEffects implements ContentList{
shocked = new StatusEffect("shocked"){{ shocked = new StatusEffect("shocked"){{
color = Pal.lancerLaser; color = Pal.lancerLaser;
reactive = true;
}}; }};
blasted = new StatusEffect("blasted"){{ blasted = new StatusEffect("blasted"){{
color = Color.valueOf("ff795e"); color = Color.valueOf("ff795e");
reactive = true;
}}; }};
corroded = new StatusEffect("corroded"){{ corroded = new StatusEffect("corroded"){{

View File

@@ -117,7 +117,7 @@ public class UnitTypes implements ContentList{
hitSize = 13f; hitSize = 13f;
rotateSpeed = 3f; rotateSpeed = 3f;
targetAir = false; targetAir = false;
health = 790; health = 800;
armor = 9f; armor = 9f;
mechFrontSway = 0.55f; mechFrontSway = 0.55f;
@@ -137,8 +137,8 @@ public class UnitTypes implements ContentList{
width = height = 14f; width = height = 14f;
collides = true; collides = true;
collidesTiles = true; collidesTiles = true;
splashDamageRadius = 24f; splashDamageRadius = 28f;
splashDamage = 45f; splashDamage = 54f;
backColor = Pal.bulletYellowBack; backColor = Pal.bulletYellowBack;
frontColor = Pal.bulletYellow; frontColor = Pal.bulletYellow;
}}; }};
@@ -150,7 +150,7 @@ public class UnitTypes implements ContentList{
hitSize = 20f; hitSize = 20f;
rotateSpeed = 2.1f; rotateSpeed = 2.1f;
health = 9000; health = 9000;
armor = 11f; armor = 10f;
canDrown = false; canDrown = false;
mechFrontSway = 1f; mechFrontSway = 1f;
@@ -173,7 +173,7 @@ public class UnitTypes implements ContentList{
inaccuracy = 3f; inaccuracy = 3f;
shotDelay = 4f; shotDelay = 4f;
bullet = new BasicBulletType(7f, 50){{ bullet = new BasicBulletType(7f, 45){{
width = 11f; width = 11f;
height = 20f; height = 20f;
lifetime = 25f; lifetime = 25f;
@@ -182,7 +182,7 @@ public class UnitTypes implements ContentList{
lightningLength = 6; lightningLength = 6;
lightningColor = Pal.surge; lightningColor = Pal.surge;
//standard bullet damage is far too much for lightning //standard bullet damage is far too much for lightning
lightningDamage = 20; lightningDamage = 19;
}}; }};
}}, }},
@@ -230,7 +230,7 @@ public class UnitTypes implements ContentList{
ejectEffect = Fx.casing4; ejectEffect = Fx.casing4;
shootSound = Sounds.bang; shootSound = Sounds.bang;
bullet = new BasicBulletType(13f, 60){{ bullet = new BasicBulletType(13f, 65){{
pierce = true; pierce = true;
pierceCap = 10; pierceCap = 10;
width = 14f; width = 14f;
@@ -247,7 +247,7 @@ public class UnitTypes implements ContentList{
fragLifeMin = 0f; fragLifeMin = 0f;
fragCone = 30f; fragCone = 30f;
fragBullet = new BasicBulletType(9f, 15){{ fragBullet = new BasicBulletType(9f, 18){{
width = 10f; width = 10f;
height = 10f; height = 10f;
pierce = true; pierce = true;
@@ -418,8 +418,8 @@ public class UnitTypes implements ContentList{
engineSize = 6f; engineSize = 6f;
lowAltitude = true; lowAltitude = true;
health = 7000f; health = 7200f;
armor = 7f; armor = 8f;
canBoost = true; canBoost = true;
landShake = 4f; landShake = 4f;
immunities = ObjectSet.with(StatusEffects.burning); immunities = ObjectSet.with(StatusEffects.burning);
@@ -435,7 +435,7 @@ public class UnitTypes implements ContentList{
firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f; firstShotDelay = Fx.greenLaserChargeSmall.lifetime - 1f;
reload = 160f; reload = 155f;
recoil = 0f; recoil = 0f;
chargeSound = Sounds.lasercharge2; chargeSound = Sounds.lasercharge2;
shootSound = Sounds.beam; shootSound = Sounds.beam;
@@ -443,8 +443,8 @@ public class UnitTypes implements ContentList{
cooldownTime = 200f; cooldownTime = 200f;
bullet = new ContinuousLaserBulletType(){{ bullet = new ContinuousLaserBulletType(){{
damage = 23f; damage = 26f;
length = 160f; length = 170f;
hitEffect = Fx.hitMeltHeal; hitEffect = Fx.hitMeltHeal;
drawSize = 420f; drawSize = 420f;
lifetime = 160f; lifetime = 160f;
@@ -454,7 +454,7 @@ public class UnitTypes implements ContentList{
shootEffect = Fx.greenLaserChargeSmall; shootEffect = Fx.greenLaserChargeSmall;
incendChance = 0.075f; incendChance = 0.08f;
incendSpread = 5f; incendSpread = 5f;
incendAmount = 1; incendAmount = 1;
@@ -565,9 +565,9 @@ public class UnitTypes implements ContentList{
hitEffect = Fx.pulverize; hitEffect = Fx.pulverize;
lifetime = 10f; lifetime = 10f;
speed = 1f; speed = 1f;
splashDamageRadius = 70f; splashDamageRadius = 58f;
instantDisappear = true; instantDisappear = true;
splashDamage = 80f; splashDamage = 85f;
killShooter = true; killShooter = true;
hittable = false; hittable = false;
collidesAir = true; collidesAir = true;
@@ -769,7 +769,7 @@ public class UnitTypes implements ContentList{
width = height = 19f; width = height = 19f;
collidesTiles = true; collidesTiles = true;
ammoMultiplier = 4f; ammoMultiplier = 4f;
splashDamageRadius = 95f; splashDamageRadius = 80f;
splashDamage = 65f; splashDamage = 65f;
backColor = Pal.sapBulletBack; backColor = Pal.sapBulletBack;
frontColor = lightningColor = Pal.sapBullet; frontColor = lightningColor = Pal.sapBullet;
@@ -867,7 +867,7 @@ public class UnitTypes implements ContentList{
width = height = 25f; width = height = 25f;
collidesTiles = collides = true; collidesTiles = collides = true;
ammoMultiplier = 4f; ammoMultiplier = 4f;
splashDamageRadius = 90f; splashDamageRadius = 80f;
splashDamage = 75f; splashDamage = 75f;
backColor = Pal.sapBulletBack; backColor = Pal.sapBulletBack;
frontColor = lightningColor = Pal.sapBullet; frontColor = lightningColor = Pal.sapBullet;
@@ -888,7 +888,7 @@ public class UnitTypes implements ContentList{
lifetime = 90f; lifetime = 90f;
width = height = 20f; width = height = 20f;
collidesTiles = false; collidesTiles = false;
splashDamageRadius = 80f; splashDamageRadius = 70f;
splashDamage = 40f; splashDamage = 40f;
backColor = Pal.sapBulletBack; backColor = Pal.sapBulletBack;
frontColor = lightningColor = Pal.sapBullet; frontColor = lightningColor = Pal.sapBullet;
@@ -1366,8 +1366,8 @@ public class UnitTypes implements ContentList{
collides = false; collides = false;
healPercent = 15f; healPercent = 15f;
splashDamage = 230f; splashDamage = 220f;
splashDamageRadius = 120f; splashDamageRadius = 80f;
}}; }};
}}); }});
}}; }};
@@ -1537,7 +1537,7 @@ public class UnitTypes implements ContentList{
width = 15f; width = 15f;
collidesTiles = false; collidesTiles = false;
ammoMultiplier = 4f; ammoMultiplier = 4f;
splashDamageRadius = 60f; splashDamageRadius = 50f;
splashDamage = 80f; splashDamage = 80f;
backColor = Pal.missileYellowBack; backColor = Pal.missileYellowBack;
frontColor = Pal.missileYellow; frontColor = Pal.missileYellow;
@@ -1590,7 +1590,7 @@ public class UnitTypes implements ContentList{
}}; }};
sei = new UnitType("sei"){{ sei = new UnitType("sei"){{
health = 10000; health = 10500;
armor = 12f; armor = 12f;
speed = 0.73f; speed = 0.73f;

View File

@@ -200,7 +200,7 @@ public class Logic implements ApplicationListener{
} }
public void skipWave(){ public void skipWave(){
state.wavetime = 0; runWave();
} }
public void runWave(){ public void runWave(){

View File

@@ -75,6 +75,7 @@ public class NetClient implements ApplicationListener{
ConnectPacket c = new ConnectPacket(); ConnectPacket c = new ConnectPacket();
c.name = player.name; c.name = player.name;
c.locale = Core.settings.getString("locale");
c.mods = mods.getModStrings(); c.mods = mods.getModStrings();
c.mobile = mobile; c.mobile = mobile;
c.versionType = Version.type; c.versionType = Version.type;
@@ -396,7 +397,6 @@ public class NetClient implements ApplicationListener{
netClient.byteStream.setBytes(net.decompressSnapshot(data, dataLen)); netClient.byteStream.setBytes(net.decompressSnapshot(data, dataLen));
DataInputStream input = netClient.dataStream; DataInputStream input = netClient.dataStream;
//go through each entity
for(int j = 0; j < amount; j++){ for(int j = 0; j < amount; j++){
int id = input.readInt(); int id = input.readInt();
byte typeID = input.readByte(); byte typeID = input.readByte();
@@ -445,11 +445,16 @@ public class NetClient implements ApplicationListener{
for(int i = 0; i < amount; i++){ for(int i = 0; i < amount; i++){
int pos = input.readInt(); int pos = input.readInt();
short block = input.readShort();
Tile tile = world.tile(pos); Tile tile = world.tile(pos);
if(tile == null || tile.build == null){ if(tile == null || tile.build == null){
Log.warn("Missing entity at @. Skipping block snapshot.", tile); Log.warn("Missing entity at @. Skipping block snapshot.", tile);
break; break;
} }
if(tile.build.block.id != block){
Log.warn("Block ID mismatch at @: @ != @. Skipping block snapshot.", tile, tile.build.block.id, block);
break;
}
tile.build.readAll(Reads.get(input), tile.build.version()); tile.build.readAll(Reads.get(input), tile.build.version());
} }
}catch(Exception e){ }catch(Exception e){
@@ -476,7 +481,7 @@ public class NetClient implements ApplicationListener{
netClient.byteStream.setBytes(net.decompressSnapshot(coreData, coreDataLen)); netClient.byteStream.setBytes(net.decompressSnapshot(coreData, coreDataLen));
DataInputStream input = netClient.dataStream; DataInputStream input = netClient.dataStream;
byte cores = input.readByte(); int cores = input.readInt();
for(int i = 0; i < cores; i++){ for(int i = 0; i < cores; i++){
int pos = input.readInt(); int pos = input.readInt();
Tile tile = world.tile(pos); Tile tile = world.tile(pos);

View File

@@ -155,7 +155,7 @@ public class NetServer implements ApplicationListener{
if(!extraMods.isEmpty()){ if(!extraMods.isEmpty()){
result.append("Unnecessary mods:[lightgray]\n").append("> ").append(extraMods.toString("\n> ")); result.append("Unnecessary mods:[lightgray]\n").append("> ").append(extraMods.toString("\n> "));
} }
con.kick(result.toString()); con.kick(result.toString(), 0);
} }
if(!admins.isWhitelisted(packet.uuid, packet.usid)){ if(!admins.isWhitelisted(packet.uuid, packet.usid)){
@@ -182,7 +182,7 @@ public class NetServer implements ApplicationListener{
return; return;
} }
if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid) || player.ip().equals(con.address))){ if(Groups.player.contains(player -> player.uuid().equals(packet.uuid) || player.usid().equals(packet.usid))){
con.kick(KickReason.idInUse); con.kick(KickReason.idInUse);
return; return;
} }
@@ -195,6 +195,10 @@ public class NetServer implements ApplicationListener{
return; return;
} }
if(packet.locale == null){
packet.locale = "en_US";
}
String ip = con.address; String ip = con.address;
admins.updatePlayerJoined(uuid, ip, packet.name); admins.updatePlayerJoined(uuid, ip, packet.name);
@@ -215,6 +219,7 @@ public class NetServer implements ApplicationListener{
player.con.uuid = uuid; player.con.uuid = uuid;
player.con.mobile = packet.mobile; player.con.mobile = packet.mobile;
player.name = packet.name; player.name = packet.name;
player.locale = packet.locale;
player.color.set(packet.color).a(1f); player.color.set(packet.color).a(1f);
//save admin ID but don't overwrite it //save admin ID but don't overwrite it
@@ -824,6 +829,7 @@ public class NetServer implements ApplicationListener{
sent ++; sent ++;
dataStream.writeInt(entity.pos()); dataStream.writeInt(entity.pos());
dataStream.writeShort(entity.block.id);
entity.writeAll(Writes.get(dataStream)); entity.writeAll(Writes.get(dataStream));
if(syncStream.size() > maxSnapshotSize){ if(syncStream.size() > maxSnapshotSize){
@@ -844,14 +850,16 @@ public class NetServer implements ApplicationListener{
public void writeEntitySnapshot(Player player) throws IOException{ public void writeEntitySnapshot(Player player) throws IOException{
syncStream.reset(); syncStream.reset();
Seq<CoreBuild> cores = state.teams.cores(player.team()); int sum = state.teams.present.sum(t -> t.cores.size);
dataStream.writeByte(cores.size); dataStream.writeInt(sum);
for(CoreBuild entity : cores){ for(TeamData data : state.teams.present){
for(CoreBuild entity : data.cores){
dataStream.writeInt(entity.tile.pos()); dataStream.writeInt(entity.tile.pos());
entity.items.write(Writes.get(dataStream)); entity.items.write(Writes.get(dataStream));
} }
}
dataStream.close(); dataStream.close();
byte[] stateBytes = syncStream.toByteArray(); byte[] stateBytes = syncStream.toByteArray();

View File

@@ -2,7 +2,6 @@ package mindustry.core;
import arc.*; import arc.*;
import arc.files.*; import arc.files.*;
import arc.fx.*;
import arc.graphics.*; import arc.graphics.*;
import arc.graphics.g2d.*; import arc.graphics.g2d.*;
import arc.graphics.gl.*; import arc.graphics.gl.*;
@@ -38,13 +37,8 @@ public class Renderer implements ApplicationListener{
public float minZoom = 1.5f, maxZoom = 6f; public float minZoom = 1.5f, maxZoom = 6f;
private @Nullable CoreBuild landCore; private @Nullable CoreBuild landCore;
//TODO unused
private FxProcessor fx = new FxProcessor();
private Color clearColor = new Color(0f, 0f, 0f, 1f); private Color clearColor = new Color(0f, 0f, 0f, 1f);
private float targetscale = Scl.scl(4); private float targetscale = Scl.scl(4), camerascale = targetscale, landscale, landTime, weatherAlpha, minZoomScl = Scl.scl(0.01f);
private float camerascale = targetscale;
private float landscale = 0f, landTime, weatherAlpha;
private float minZoomScl = Scl.scl(0.01f);
private float shakeIntensity, shaketime; private float shakeIntensity, shaketime;
public Renderer(){ public Renderer(){
@@ -73,7 +67,6 @@ public class Renderer implements ApplicationListener{
@Override @Override
public void update(){ public void update(){
Color.white.set(1f, 1f, 1f, 1f); Color.white.set(1f, 1f, 1f, 1f);
Gl.clear(Gl.stencilBufferBit);
float dest = Mathf.round(targetscale, 0.5f); float dest = Mathf.round(targetscale, 0.5f);
camerascale = Mathf.lerpDelta(camerascale, dest, 0.1f); camerascale = Mathf.lerpDelta(camerascale, dest, 0.1f);
@@ -136,11 +129,6 @@ public class Renderer implements ApplicationListener{
Events.fire(new DisposeEvent()); Events.fire(new DisposeEvent());
} }
@Override
public void resize(int width, int height){
fx.resize(width, height);
}
@Override @Override
public void resume(){ public void resume(){
if(settings.getBool("bloom") && bloom != null){ if(settings.getBool("bloom") && bloom != null){
@@ -175,23 +163,6 @@ public class Renderer implements ApplicationListener{
} }
} }
void beginFx(){
if(!fx.hasEnabledEffects()) return;
Draw.flush();
fx.clear();
fx.begin();
}
void endFx(){
if(!fx.hasEnabledEffects()) return;
Draw.flush();
fx.end();
fx.applyEffects();
fx.render(0, 0, fx.getWidth(), fx.getHeight());
}
void updateShake(float scale){ void updateShake(float scale){
if(shaketime > 0){ if(shaketime > 0){
float intensity = shakeIntensity * (settings.getInt("screenshake", 4) / 4f) * scale; float intensity = shakeIntensity * (settings.getInt("screenshake", 4) / 4f) * scale;
@@ -236,7 +207,7 @@ public class Renderer implements ApplicationListener{
Draw.draw(Layer.background, this::drawBackground); Draw.draw(Layer.background, this::drawBackground);
Draw.draw(Layer.floor, blocks.floor::drawFloor); Draw.draw(Layer.floor, blocks.floor::drawFloor);
Draw.draw(Layer.block - 1, blocks::drawShadows); Draw.draw(Layer.block - 1, blocks::drawShadows);
Draw.draw(Layer.block, () -> { Draw.draw(Layer.block - 0.09f, () -> {
blocks.floor.beginDraw(); blocks.floor.beginDraw();
blocks.floor.drawLayer(CacheLayer.walls); blocks.floor.drawLayer(CacheLayer.walls);
blocks.floor.endDraw(); blocks.floor.endDraw();

View File

@@ -108,7 +108,7 @@ public class UI implements ApplicationListener, Loadable{
Dialog.setHideAction(() -> sequence(fadeOut(0.1f))); Dialog.setHideAction(() -> sequence(fadeOut(0.1f)));
Tooltips.getInstance().animations = false; Tooltips.getInstance().animations = false;
Tooltips.getInstance().textProvider = text -> new Tooltip(t -> t.background(Styles.black5).margin(4f).add(text)); Tooltips.getInstance().textProvider = text -> new Tooltip(t -> t.background(Styles.black6).margin(4f).add(text));
Core.settings.setErrorHandler(e -> { Core.settings.setErrorHandler(e -> {
Log.err(e); Log.err(e);
@@ -214,6 +214,13 @@ public class UI implements ApplicationListener, Loadable{
@Override @Override
public void resize(int width, int height){ public void resize(int width, int height){
if(Core.scene == null) return; if(Core.scene == null) return;
int[] insets = Core.graphics.getSafeInsets();
Core.scene.marginLeft = insets[0];
Core.scene.marginRight = insets[1];
Core.scene.marginTop = insets[2];
Core.scene.marginBottom = insets[3];
Core.scene.resize(width, height); Core.scene.resize(width, height);
Events.fire(new ResizeEvent()); Events.fire(new ResizeEvent());
} }
@@ -363,6 +370,16 @@ public class UI implements ApplicationListener, Loadable{
}}.show(); }}.show();
} }
public void showInfoOnHidden(String info, Runnable listener){
new Dialog(""){{
getCell(cont).growX();
cont.margin(15).add(info).width(400f).wrap().get().setAlignment(Align.center, Align.center);
buttons.button("@ok", this::hide).size(110, 50).pad(4);
hidden(listener);
closeOnBack();
}}.show();
}
public void showStartupInfo(String info){ public void showStartupInfo(String info){
new Dialog(""){{ new Dialog(""){{
getCell(cont).growX(); getCell(cont).growX();
@@ -526,16 +543,15 @@ public class UI implements ApplicationListener, Loadable{
dialog.show(); dialog.show();
} }
//TODO move?
public static String formatAmount(int number){ public static String formatAmount(int number){
if(number >= 1_000_000_000){ int mag = Math.abs(number);
if(mag >= 1_000_000_000){
return Strings.fixed(number / 1_000_000_000f, 1) + "[gray]" + Core.bundle.get("unit.billions") + "[]"; return Strings.fixed(number / 1_000_000_000f, 1) + "[gray]" + Core.bundle.get("unit.billions") + "[]";
}else if(number >= 1_000_000){ }else if(mag >= 1_000_000){
return Strings.fixed(number / 1_000_000f, 1) + "[gray]" + Core.bundle.get("unit.millions") + "[]"; return Strings.fixed(number / 1_000_000f, 1) + "[gray]" + Core.bundle.get("unit.millions") + "[]";
}else if(number >= 10_000){ }else if(mag >= 10_000){
return number / 1000 + "[gray]" + Core.bundle.get("unit.thousands") + "[]"; return number / 1000 + "[gray]" + Core.bundle.get("unit.thousands") + "[]";
}else if(number >= 1000){ }else if(mag >= 1000){
return Strings.fixed(number / 1000f, 1) + "[gray]" + Core.bundle.get("unit.thousands") + "[]"; return Strings.fixed(number / 1000f, 1) + "[gray]" + Core.bundle.get("unit.thousands") + "[]";
}else{ }else{
return number + ""; return number + "";

View File

@@ -4,6 +4,7 @@ import arc.*;
import arc.func.*; import arc.func.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.math.geom.Geometry.*;
import arc.struct.*; import arc.struct.*;
import arc.struct.ObjectIntMap.*; import arc.struct.ObjectIntMap.*;
import arc.util.*; import arc.util.*;
@@ -554,10 +555,6 @@ public class World{
return dark; return dark;
} }
public interface Raycaster{
boolean accept(int x, int y);
}
private class Context implements WorldContext{ private class Context implements WorldContext{
Context(){ Context(){

View File

@@ -8,6 +8,7 @@ import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.editor.DrawOperation.*; import mindustry.editor.DrawOperation.*;
import mindustry.entities.units.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.io.*; import mindustry.io.*;
@@ -259,7 +260,7 @@ public class MapEditor{
clearOp(); clearOp();
Tiles previous = world.tiles; Tiles previous = world.tiles;
int offsetX = -(width - width()) / 2, offsetY = -(height - height()) / 2; int offsetX = (width() - width) / 2, offsetY = (height() - height) / 2;
loading = true; loading = true;
Tiles tiles = world.resize(width, height); Tiles tiles = world.resize(width, height);
@@ -275,7 +276,17 @@ public class MapEditor{
if(tile.build != null && tile.isCenter()){ if(tile.build != null && tile.isCenter()){
tile.build.x = x * tilesize + tile.block().offset; tile.build.x = x * tilesize + tile.block().offset;
tile.build.y = y * tilesize + tile.block().offset; tile.build.y = y * tilesize + tile.block().offset;
//shift links to account for map resize
Object config = tile.build.config();
if(config != null){
Object out = BuildPlan.pointConfig(tile.block(), config, p -> p.sub(offsetX, offsetY));
if(out != config){
tile.build.configureAny(out);
} }
}
}
}else{ }else{
tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0)); tiles.set(x, y, new EditorTile(x, y, Blocks.stone.id, (short)0, (short)0));
} }

View File

@@ -156,7 +156,10 @@ public class MapEditorDialog extends Dialog implements Disposable{
} }
platform.publish(map); platform.publish(map);
}).padTop(-3).size(swidth * 2f + 10, 60f).update(b -> b.setText(editor.tags.containsKey("steamid") ? editor.tags.get("author").equals(player.name) ? "@workshop.listing" : "@view.workshop" : "@editor.publish.workshop")); }).padTop(-3).size(swidth * 2f + 10, 60f).update(b ->
b.setText(editor.tags.containsKey("steamid") ?
editor.tags.get("author").equals(steamPlayerName) ? "@workshop.listing" : "@view.workshop" :
"@editor.publish.workshop"));
menu.cont.row(); menu.cont.row();
} }
@@ -263,7 +266,9 @@ public class MapEditorDialog extends Dialog implements Disposable{
if(player.team().core() == null){ if(player.team().core() == null){
player.set(world.width() * tilesize/2f, world.height() * tilesize/2f); player.set(world.width() * tilesize/2f, world.height() * tilesize/2f);
player.unit(UnitTypes.alpha.spawn(player.team(), player.x, player.y)); var unit = UnitTypes.alpha.spawn(player.team(), player.x, player.y);
unit.spawnedByCore = true;
player.unit(unit);
} }
}); });
} }

View File

@@ -285,29 +285,31 @@ public class MapGenerateDialog extends BaseDialog{
void showAdd(){ void showAdd(){
BaseDialog selection = new BaseDialog("@add"); BaseDialog selection = new BaseDialog("@add");
selection.setFillParent(false); selection.cont.pane(p -> {
selection.cont.defaults().size(210f, 60f); p.marginRight(14);
p.defaults().size(210f, 60f);
int i = 0; int i = 0;
for(Prov<GenerateFilter> gen : filterTypes){ for(Prov<GenerateFilter> gen : filterTypes){
GenerateFilter filter = gen.get(); GenerateFilter filter = gen.get();
if((filter.isPost() && applied)) continue; if((filter.isPost() && applied)) continue;
selection.cont.button(filter.name(), () -> { p.button(filter.name(), () -> {
filters.add(filter); filters.add(filter);
rebuildFilters(); rebuildFilters();
update(); update();
selection.hide(); selection.hide();
}); });
if(++i % 2 == 0) selection.cont.row(); if(++i % 2 == 0) p.row();
} }
selection.cont.button("@filter.defaultores", () -> { p.button("@filter.defaultores", () -> {
maps.addDefaultOres(filters); maps.addDefaultOres(filters);
rebuildFilters(); rebuildFilters();
update(); update();
selection.hide(); selection.hide();
}); });
}).get().setScrollingDisabled(true, false);
selection.addCloseButton(); selection.addCloseButton();
selection.show(); selection.show();

View File

@@ -6,7 +6,6 @@ import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
@@ -25,11 +24,10 @@ public class Damage{
private static Rect hitrect = new Rect(); private static Rect hitrect = new Rect();
private static Vec2 tr = new Vec2(), seg1 = new Vec2(), seg2 = new Vec2(); private static Vec2 tr = new Vec2(), seg1 = new Vec2(), seg2 = new Vec2();
private static Seq<Unit> units = new Seq<>(); private static Seq<Unit> units = new Seq<>();
private static GridBits bits = new GridBits(30, 30);
private static IntQueue propagation = new IntQueue();
private static IntSet collidedBlocks = new IntSet(); private static IntSet collidedBlocks = new IntSet();
private static Building tmpBuilding; private static Building tmpBuilding;
private static Unit tmpUnit; private static Unit tmpUnit;
private static IntFloatMap damages = new IntFloatMap();
/** Creates a dynamic explosion based on specified parameters. */ /** Creates a dynamic explosion based on specified parameters. */
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage){ public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage){
@@ -39,9 +37,9 @@ public class Damage{
/** Creates a dynamic explosion based on specified parameters. */ /** Creates a dynamic explosion based on specified parameters. */
public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage, boolean fire, @Nullable Team ignoreTeam){ public static void dynamicExplosion(float x, float y, float flammability, float explosiveness, float power, float radius, boolean damage, boolean fire, @Nullable Team ignoreTeam){
if(damage){ if(damage){
for(int i = 0; i < Mathf.clamp(power / 20, 0, 6); i++){ for(int i = 0; i < Mathf.clamp(power / 700, 0, 8); i++){
int branches = 5 + Mathf.clamp((int)(power / 30), 1, 20); int length = 5 + Mathf.clamp((int)(power / 500), 1, 20);
Time.run(i * 2f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), branches + Mathf.range(2))); Time.run(i * 0.8f + Mathf.random(4f), () -> Lightning.create(Team.derelict, Pal.power, 3, x, y, Mathf.random(360f), length + Mathf.range(2)));
} }
if(fire){ if(fire){
@@ -116,7 +114,15 @@ public class Damage{
* Only enemies of the specified team are damaged. * Only enemies of the specified team are damaged.
*/ */
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){ public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large){
length = findLaserLength(hitter, length); collideLine(hitter, team, effect, x, y, angle, length, large, true);
}
/**
* Damages entities in a line.
* Only enemies of the specified team are damaged.
*/
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length, boolean large, boolean laser){
if(laser) length = findLaserLength(hitter, length);
collidedBlocks.clear(); collidedBlocks.clear();
tr.trns(angle, length); tr.trns(angle, length);
@@ -207,9 +213,9 @@ public class Damage{
public static Healthc linecast(Bullet hitter, float x, float y, float angle, float length){ public static Healthc linecast(Bullet hitter, float x, float y, float angle, float length){
tr.trns(angle, length); tr.trns(angle, length);
if(hitter.type.collidesGround){
tmpBuilding = null; tmpBuilding = null;
if(hitter.type.collidesGround){
world.raycastEachWorld(x, y, x + tr.x, y + tr.y, (cx, cy) -> { world.raycastEachWorld(x, y, x + tr.x, y + tr.y, (cx, cy) -> {
Building tile = world.build(cx, cy); Building tile = world.build(cx, cy);
if(tile != null && tile.team != hitter.team){ if(tile != null && tile.team != hitter.team){
@@ -218,8 +224,6 @@ public class Damage{
} }
return false; return false;
}); });
if(tmpBuilding != null) return tmpBuilding;
} }
rect.setPosition(x, y).setSize(tr.x, tr.y); rect.setPosition(x, y).setSize(tr.x, tr.y);
@@ -263,6 +267,14 @@ public class Damage{
Units.nearbyEnemies(hitter.team, rect, cons); Units.nearbyEnemies(hitter.team, rect, cons);
if(tmpBuilding != null && tmpUnit != null){
if(Mathf.dst2(x, y, tmpUnit.getX(), tmpUnit.getY()) <= Mathf.dst2(x, y, tmpBuilding.getX(), tmpBuilding.getY())){
return tmpUnit;
}
}else if(tmpBuilding != null){
return tmpBuilding;
}
return tmpUnit; return tmpUnit;
} }
@@ -351,64 +363,85 @@ public class Damage{
if(ground){ if(ground){
if(!complete){ if(!complete){
int trad = (int)(radius / tilesize); //increase damage slightly to compensate for new algorithm
Tile tile = world.tileWorld(x, y); tileDamage(team, World.toTile(x), World.toTile(y), radius / tilesize, damage * 1.1f);
if(tile != null){
tileDamage(team, tile.x, tile.y, trad, damage);
}
}else{ }else{
completeDamage(team, x, y, radius, damage); completeDamage(team, x, y, radius, damage);
} }
} }
} }
public static void tileDamage(Team team, int startx, int starty, int baseRadius, float baseDamage){ public static void tileDamage(Team team, int x, int y, float baseRadius, float damage){
//tile damage is posted, so that destroying a block that causes a chain explosion will run in the next frame
//this prevents recursive damage calls from messing up temporary variables
Core.app.post(() -> { Core.app.post(() -> {
bits.clear(); var in = world.build(x, y);
propagation.clear(); //spawned inside a multiblock. this means that damage needs to be dealt directly.
int bitOffset = bits.width() / 2; //why? because otherwise the building would absorb everything in one cell, which means much less damage than a nearby explosion.
//this needs to be compensated
if(in != null && in.team != team && in.block.size > 1 && in.health > damage){
//deal the damage of an entire side + 1, to be equivalent with maximum 'standard' damage
in.damage(damage * (in.block.size + 1));
//no need to continue with the explosion
return;
}
propagation.addFirst(PropCell.get((byte)0, (byte)0, (short)baseDamage)); //cap radius to prevent lag
//clamp radius to fit bits float radius = Math.min(baseRadius, 30), rad2 = radius * radius;
int radius = Math.min(baseRadius, bits.width() / 2); int rays = Mathf.ceil(radius * 2 * Mathf.pi);
double spacing = Math.PI * 2.0 / rays;
damages.clear();
while(!propagation.isEmpty()){ //raycast from each angle
int prop = propagation.removeLast(); for(int i = 0; i <= rays; i++){
int x = PropCell.x(prop); float dealt = 0f;
int y = PropCell.y(prop); int startX = x;
int damage = PropCell.damage(prop); int startY = y;
//manhattan distance used for calculating falloff, results in a diamond pattern int endX = x + (int)(Math.cos(spacing * i) * radius), endY = y + (int)(Math.sin(spacing * i) * radius);
int dst = Math.abs(x) + Math.abs(y);
int scaledDamage = (int)(damage * (1f - (float)dst / radius)); int xDist = Math.abs(endX - startX);
int yDist = -Math.abs(endY - startY);
int xStep = (startX < endX ? +1 : -1);
int yStep = (startY < endY ? +1 : -1);
int error = xDist + yDist;
bits.set(bitOffset + x, bitOffset + y); while(startX != endX || startY != endY){
Tile tile = world.tile(startx + x, starty + y); var build = world.build(startX, startY);
if(build != null && build.team != team){
//damage dealt at circle edge
float edgeScale = 0.6f;
float mult = (1f-(Mathf.dst2(startX, startY, x, y) / rad2) + edgeScale) / (1f + edgeScale);
float next = damage * mult - dealt;
//register damage dealt
int p = Point2.pack(startX, startY);
damages.put(p, Math.max(damages.get(p), next));
//register as hit
dealt += build.health;
if(scaledDamage <= 0 || tile == null) continue; if(next - dealt <= 0){
break;
//apply damage to entity if needed
if(tile.build != null && tile.build.team != team){
int health = (int)(tile.build.health / (tile.block().size * tile.block().size));
if(tile.build.health > 0){
tile.build.damage(scaledDamage);
scaledDamage -= health;
if(scaledDamage <= 0) continue;
} }
} }
for(Point2 p : Geometry.d4){ if(2 * error - yDist > xDist - 2 * error){
if(!bits.get(bitOffset + x + p.x, bitOffset + y + p.y)){ error += yDist;
propagation.addFirst(PropCell.get((byte)(x + p.x), (byte)(y + p.y), (short)scaledDamage)); startX += xStep;
}else{
error += xDist;
startY += yStep;
} }
} }
} }
//apply damage
for(var e : damages){
int cx = Point2.x(e.key), cy = Point2.y(e.key);
var build = world.build(cx, cy);
if(build != null){
build.damage(e.value);
}
}
}); });
} }
private static void completeDamage(Team team, float x, float y, float radius, float damage){ private static void completeDamage(Team team, float x, float y, float radius, float damage){
@@ -429,11 +462,4 @@ public class Damage{
float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff); float scaled = Mathf.lerp(1f - dist / radius, 1f, falloff);
return damage * scaled; return damage * scaled;
} }
@Struct
static class PropCellStruct{
byte x;
byte y;
short damage;
}
} }

View File

@@ -3,6 +3,7 @@ package mindustry.entities;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import mindustry.content.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.world.*; import mindustry.world.*;
@@ -126,7 +127,7 @@ public class EntityCollisions{
public static boolean legsSolid(int x, int y){ public static boolean legsSolid(int x, int y){
Tile tile = world.tile(x, y); Tile tile = world.tile(x, y);
return tile == null || tile.staticDarkness() >= 2 || tile.floor().solid; return tile == null || tile.staticDarkness() >= 2 || (tile.floor().solid && tile.block() == Blocks.air);
} }
public static boolean waterSolid(int x, int y){ public static boolean waterSolid(int x, int y){
@@ -190,14 +191,10 @@ public class EntityCollisions{
yInvExit = y2 - (y1 + h1); yInvExit = y2 - (y1 + h1);
} }
float xEntry, yEntry; float xEntry = xInvEntry / vx1;
float xExit, yExit; float xExit = xInvExit / vx1;
float yEntry = yInvEntry / vy1;
xEntry = xInvEntry / vx1; float yExit = yInvExit / vy1;
xExit = xInvExit / vx1;
yEntry = yInvEntry / vy1;
yExit = yInvExit / vy1;
float entryTime = Math.max(xEntry, yEntry); float entryTime = Math.max(xEntry, yEntry);
float exitTime = Math.min(xExit, yExit); float exitTime = Math.min(xExit, yExit);

View File

@@ -6,6 +6,7 @@ import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.entities.comp.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.game.Teams.*; import mindustry.game.Teams.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -75,7 +76,7 @@ public class Units{
if((team == state.rules.waveTeam && !state.rules.pvp) || (state.isCampaign() && team == state.rules.waveTeam)){ if((team == state.rules.waveTeam && !state.rules.pvp) || (state.isCampaign() && team == state.rules.waveTeam)){
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
return state.rules.unitCap + indexer.getExtraUnits(team); return Math.max(0, state.rules.unitCapVariable ? state.rules.unitCap + indexer.getExtraUnits(team) : state.rules.unitCap);
} }
/** @return whether this player can interact with a specific tile. if either of these are null, returns true.*/ /** @return whether this player can interact with a specific tile. if either of these are null, returns true.*/
@@ -93,7 +94,7 @@ public class Units{
* @return whether the target is invalid * @return whether the target is invalid
*/ */
public static boolean invalidateTarget(Posc target, Team team, float x, float y, float range){ public static boolean invalidateTarget(Posc target, Team team, float x, float y, float range){
return target == null || (range != Float.MAX_VALUE && !target.within(x, y, range)) || (target instanceof Teamc && ((Teamc)target).team() == team) || (target instanceof Healthc && !((Healthc)target).isValid()); return target == null || (range != Float.MAX_VALUE && !target.within(x, y, range + (target instanceof Sized hb ? hb.hitSize()/2f : 0f))) || (target instanceof Teamc t && t.team() == team) || (target instanceof Healthc h && !h.isValid());
} }
/** See {@link #invalidateTarget(Posc, Team, float, float, float)} */ /** See {@link #invalidateTarget(Posc, Team, float, float, float)} */
@@ -217,7 +218,7 @@ public class Units{
cdist = 0f; cdist = 0f;
nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> { nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> {
if(e.dead() || !predicate.get(e) || !e.within(x, y, range)) return; if(e.dead() || !predicate.get(e) || !e.within(x, y, range + e.hitSize/2f)) return;
float cost = sort.cost(e, x, y); float cost = sort.cost(e, x, y);
if(result == null || cost < cdist){ if(result == null || cost < cdist){
@@ -292,7 +293,7 @@ public class Units{
/** Iterates over all units in a circle around this position. */ /** Iterates over all units in a circle around this position. */
public static void nearby(Team team, float x, float y, float radius, Cons<Unit> cons){ public static void nearby(Team team, float x, float y, float radius, Cons<Unit> cons){
nearby(team, x - radius, y - radius, radius*2f, radius*2f, unit -> { nearby(team, x - radius, y - radius, radius*2f, radius*2f, unit -> {
if(unit.within(x, y, radius)){ if(unit.within(x, y, radius + unit.hitSize/2f)){
cons.get(unit); cons.get(unit);
} }
}); });

View File

@@ -273,7 +273,7 @@ public abstract class BulletType extends Content{
if(homingPower > 0.0001f && b.time >= homingDelay){ if(homingPower > 0.0001f && b.time >= homingDelay){
Teamc target = Units.closestTarget(b.team, b.x, b.y, homingRange, e -> (e.isGrounded() && collidesGround) || (e.isFlying() && collidesAir), t -> collidesGround); Teamc target = Units.closestTarget(b.team, b.x, b.y, homingRange, e -> (e.isGrounded() && collidesGround) || (e.isFlying() && collidesAir), t -> collidesGround);
if(target != null){ if(target != null){
b.vel.setAngle(Mathf.slerpDelta(b.rotation(), b.angleTo(target), homingPower)); b.vel.setAngle(Angles.moveToward(b.rotation(), b.angleTo(target), homingPower * Time.delta * 50f));
} }
} }

View File

@@ -8,8 +8,8 @@ import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
public class LightningBulletType extends BulletType{ public class LightningBulletType extends BulletType{
protected Color lightningColor = Pal.lancerLaser; public Color lightningColor = Pal.lancerLaser;
protected int lightningLength = 25, lightningLengthRand = 0; public int lightningLength = 25, lightningLengthRand = 0;
public LightningBulletType(){ public LightningBulletType(){
super(0.0001f, 1f); super(0.0001f, 1f);

View File

@@ -54,7 +54,7 @@ public class RailBulletType extends BulletType{
super.init(b); super.init(b);
b.fdata = length; b.fdata = length;
Damage.collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), length, false); Damage.collideLine(b, b.team, b.type.hitEffect, b.x, b.y, b.rotation(), length, false, false);
float resultLen = b.fdata; float resultLen = b.fdata;
Vec2 nor = Tmp.v1.set(b.vel).nor(); Vec2 nor = Tmp.v1.set(b.vel).nor();

View File

@@ -43,7 +43,7 @@ import static mindustry.Vars.*;
@EntityDef(value = {Buildingc.class}, isFinal = false, genio = false, serialize = false) @EntityDef(value = {Buildingc.class}, isFinal = false, genio = false, serialize = false)
@Component(base = true) @Component(base = true)
abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable, Senseable, Controllable{ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, QuadTreeObject, Displayable, Senseable, Controllable, Sized{
//region vars and initialization //region vars and initialization
static final float timeToSleep = 60f * 1, timeToUncontrol = 60f * 6; static final float timeToSleep = 60f * 1, timeToUncontrol = 60f * 6;
static final ObjectSet<Building> tmpTiles = new ObjectSet<>(); static final ObjectSet<Building> tmpTiles = new ObjectSet<>();
@@ -536,6 +536,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
} }
public void dumpLiquid(Liquid liquid){ public void dumpLiquid(Liquid liquid){
dumpLiquid(liquid, 2f);
}
public void dumpLiquid(Liquid liquid, float scaling){
int dump = this.cdump; int dump = this.cdump;
if(liquids.get(liquid) <= 0.0001f) return; if(liquids.get(liquid) <= 0.0001f) return;
@@ -551,10 +555,9 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
float ofract = other.liquids.get(liquid) / other.block.liquidCapacity; float ofract = other.liquids.get(liquid) / other.block.liquidCapacity;
float fract = liquids.get(liquid) / block.liquidCapacity; float fract = liquids.get(liquid) / block.liquidCapacity;
if(ofract < fract) transferLiquid(other, (fract - ofract) * block.liquidCapacity / 2f, liquid); if(ofract < fract) transferLiquid(other, (fract - ofract) * block.liquidCapacity / scaling, liquid);
} }
} }
} }
public boolean canDumpLiquid(Building to, Liquid liquid){ public boolean canDumpLiquid(Building to, Liquid liquid){
@@ -789,6 +792,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
for(Building other : proximity){ for(Building other : proximity){
if(other != null && other.power != null if(other != null && other.power != null
&& other.team == team
&& !(block.consumesPower && other.block.consumesPower && !block.outputsPower && !other.block.outputsPower) && !(block.consumesPower && other.block.consumesPower && !block.outputsPower && !other.block.outputsPower)
&& conductsTo(other) && other.conductsTo(self()) && !power.links.contains(other.pos())){ && conductsTo(other) && other.conductsTo(self()) && !power.links.contains(other.pos())){
out.add(other); out.add(other);
@@ -797,7 +801,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
for(int i = 0; i < power.links.size; i++){ for(int i = 0; i < power.links.size; i++){
Tile link = world.tile(power.links.get(i)); Tile link = world.tile(power.links.get(i));
if(link != null && link.build != null && link.build.power != null) out.add(link.build); if(link != null && link.build != null && link.build.power != null && link.build.team == team) out.add(link.build);
} }
return out; return out;
} }
@@ -979,6 +983,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
int amount = items.get(item); int amount = items.get(item);
explosiveness += item.explosiveness * amount; explosiveness += item.explosiveness * amount;
flammability += item.flammability * amount; flammability += item.flammability * amount;
power += item.charge * amount * 100f;
} }
} }
@@ -1273,6 +1278,11 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
return tile.build == self() && !dead(); return tile.build == self() && !dead();
} }
@Override
public float hitSize(){
return tile.block().size * tilesize;
}
@Replace @Replace
@Override @Override
public void kill(){ public void kill(){
@@ -1306,6 +1316,8 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
case health -> health; case health -> health;
case maxHealth -> maxHealth; case maxHealth -> maxHealth;
case efficiency -> efficiency(); case efficiency -> efficiency();
case timescale -> timeScale;
case range -> this instanceof Ranged r ? r.range() / tilesize : 0;
case rotation -> rotation; case rotation -> rotation;
case totalItems -> items == null ? 0 : items.total(); case totalItems -> items == null ? 0 : items.total();
case totalLiquids -> liquids == null ? 0 : liquids.total(); case totalLiquids -> liquids == null ? 0 : liquids.total();
@@ -1320,7 +1332,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
case enabled -> enabled ? 1 : 0; case enabled -> enabled ? 1 : 0;
case controlled -> this instanceof ControlBlock c ? c.isControlled() ? 1 : 0 : 0; case controlled -> this instanceof ControlBlock c ? c.isControlled() ? 1 : 0 : 0;
case payloadCount -> getPayload() != null ? 1 : 0; case payloadCount -> getPayload() != null ? 1 : 0;
default -> 0; default -> Float.NaN; //gets converted to null in logic
}; };
} }
@@ -1333,14 +1345,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
case payloadType -> getPayload() instanceof UnitPayload p1 ? p1.unit.type : getPayload() instanceof BuildPayload p2 ? p2.block() : null; case payloadType -> getPayload() instanceof UnitPayload p1 ? p1.unit.type : getPayload() instanceof BuildPayload p2 ? p2.block() : null;
default -> noSensed; default -> noSensed;
}; };
} }
@Override @Override
public double sense(Content content){ public double sense(Content content){
if(content instanceof Item && items != null) return items.get((Item)content); if(content instanceof Item i && items != null) return items.get(i);
if(content instanceof Liquid && liquids != null) return liquids.get((Liquid)content); if(content instanceof Liquid l && liquids != null) return liquids.get(l);
return 0; return Float.NaN; //invalid sense
} }
@Override @Override

View File

@@ -80,6 +80,7 @@ abstract class CommanderComp implements Entityc, Posc{
void command(Formation formation, Seq<Unit> units){ void command(Formation formation, Seq<Unit> units){
clearCommand(); clearCommand();
units.shuffle();
float spacing = hitSize * 0.8f; float spacing = hitSize * 0.8f;
minFormationSpeed = type.speed; minFormationSpeed = type.speed;

View File

@@ -8,7 +8,7 @@ import mindustry.annotations.Annotations.*;
import mindustry.gen.*; import mindustry.gen.*;
@Component @Component
abstract class HitboxComp implements Posc, QuadTreeObject{ abstract class HitboxComp implements Posc, Sized, QuadTreeObject{
@Import float x, y; @Import float x, y;
transient float lastX, lastY, deltaX, deltaY, hitSize; transient float lastX, lastY, deltaX, deltaY, hitSize;
@@ -28,6 +28,11 @@ abstract class HitboxComp implements Posc, QuadTreeObject{
updateLastPosition(); updateLastPosition();
} }
@Override
public float hitSize(){
return hitSize;
}
void getCollisions(Cons<QuadTree> consumer){ void getCollisions(Cons<QuadTree> consumer){
} }

View File

@@ -43,6 +43,8 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
String name = "noname"; String name = "noname";
Color color = new Color(); Color color = new Color();
//locale should not be synced.
transient String locale = "en";
transient float deathTimer; transient float deathTimer;
transient String lastText = ""; transient String lastText = "";
transient float textFadeTime; transient float textFadeTime;

View File

@@ -0,0 +1,5 @@
package mindustry.entities.comp;
public interface Sized{
float hitSize();
}

View File

@@ -55,11 +55,17 @@ abstract class StatusComp implements Posc, Flyingc{
} }
} }
if(!effect.reactive){
//otherwise, no opposites found, add direct effect //otherwise, no opposites found, add direct effect
StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new); StatusEntry entry = Pools.obtain(StatusEntry.class, StatusEntry::new);
entry.set(effect, duration); entry.set(effect, duration);
statuses.add(entry); statuses.add(entry);
} }
}
void clearStatuses(){
statuses.clear();
}
/** Removes a status effect. */ /** Removes a status effect. */
void unapply(StatusEffect effect){ void unapply(StatusEffect effect){

View File

@@ -53,7 +53,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
} }
public void approach(Vec2 vector){ public void approach(Vec2 vector){
vel.approachDelta(vector, type.accel * realSpeed() * floorSpeedMultiplier()); vel.approachDelta(vector, type.accel * realSpeed());
} }
public void aimLook(Position pos){ public void aimLook(Position pos){
@@ -82,7 +82,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
/** @return speed with boost multipliers factored in. */ /** @return speed with boost multipliers factored in. */
public float realSpeed(){ public float realSpeed(){
return Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation) * speed(); return Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, elevation) * speed() * floorSpeedMultiplier();
} }
/** Iterates through this unit and everything it is controlling. */ /** Iterates through this unit and everything it is controlling. */
@@ -130,6 +130,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
case y -> World.conv(y); case y -> World.conv(y);
case team -> team.id; case team -> team.id;
case shooting -> isShooting() ? 1 : 0; case shooting -> isShooting() ? 1 : 0;
case range -> range() / tilesize;
case shootX -> World.conv(aimX()); case shootX -> World.conv(aimX());
case shootY -> World.conv(aimY()); case shootY -> World.conv(aimY());
case mining -> mining() ? 1 : 0; case mining -> mining() ? 1 : 0;
@@ -410,9 +411,10 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f; float explosiveness = 2f + item().explosiveness * stack().amount * 1.53f;
float flammability = item().flammability * stack().amount / 1.9f; float flammability = item().flammability * stack().amount / 1.9f;
float power = item().charge * stack().amount * 150f;
if(!spawnedByCore){ if(!spawnedByCore){
Damage.dynamicExplosion(x, y, flammability, explosiveness, 0f, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team); Damage.dynamicExplosion(x, y, flammability, explosiveness, power, bounds() / 2f, state.rules.damageExplosions, item().flammability > 1, team);
} }
float shake = hitSize / 3f; float shake = hitSize / 3f;

View File

@@ -1,6 +1,5 @@
package mindustry.entities.comp; package mindustry.entities.comp;
import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.util.*; import arc.util.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
@@ -22,7 +21,7 @@ abstract class VelComp implements Posc{
@Override @Override
public void update(){ public void update(){
move(vel.x * Time.delta, vel.y * Time.delta); move(vel.x * Time.delta, vel.y * Time.delta);
vel.scl(Mathf.clamp(1f - drag * Time.delta)); vel.scl(Math.max(1f - drag * Time.delta, 0));
} }
/** @return function to use for check solid state. if null, no checking is done. */ /** @return function to use for check solid state. if null, no checking is done. */

View File

@@ -19,13 +19,19 @@ public class MultiEffect extends Effect{
public void init(){ public void init(){
for(Effect f : effects){ for(Effect f : effects){
clip = Math.max(clip, f.clip); clip = Math.max(clip, f.clip);
lifetime = Math.max(lifetime, f.lifetime);
} }
} }
@Override @Override
public void render(EffectContainer e){ public void render(EffectContainer e){
int index = 0;
for(Effect f : effects){ for(Effect f : effects){
e.scaled(f.lifetime, f::render); int i = ++index;
e.scaled(f.lifetime, cont -> {
cont.id = e.id + i;
f.render(cont);
});
clip = Math.max(clip, f.clip); clip = Math.max(clip, f.clip);
} }
} }

View File

@@ -16,6 +16,7 @@ public class ParticleEffect extends Effect{
//region only //region only
public float sizeFrom = 2f, sizeTo = 0f; public float sizeFrom = 2f, sizeTo = 0f;
public float offset = 0;
public String region = "circle"; public String region = "circle";
//line only //line only
@@ -48,7 +49,7 @@ public class ParticleEffect extends Effect{
}); });
}else{ }else{
Angles.randLenVectors(e.id, particles, length * fin + baseLength, e.rotation, cone, (x, y) -> { Angles.randLenVectors(e.id, particles, length * fin + baseLength, e.rotation, cone, (x, y) -> {
Draw.rect(tex, e.x + x, e.y + y, rad, rad); Draw.rect(tex, e.x + x, e.y + y, rad, rad, e.rotation + offset);
}); });
} }
} }

View File

@@ -15,7 +15,7 @@ import static mindustry.Vars.*;
public class AIController implements UnitController{ public class AIController implements UnitController{
protected static final Vec2 vec = new Vec2(); protected static final Vec2 vec = new Vec2();
protected static final int timerTarget = 0, timerTarget2 = 1, timerTarget3 = 2; protected static final int timerTarget = 0, timerTarget2 = 1, timerTarget3 = 2, timerTarget4 = 3;
protected Unit unit; protected Unit unit;
protected Interval timer = new Interval(4); protected Interval timer = new Interval(4);

View File

@@ -68,6 +68,8 @@ public class EventType{
public static class ContentInitEvent{} public static class ContentInitEvent{}
/** Called when the client game is first loaded. */ /** Called when the client game is first loaded. */
public static class ClientLoadEvent{} public static class ClientLoadEvent{}
/** Called *after* all the modded files have been added into Vars.tree */
public static class FileTreeInitEvent{}
/** Called when a game begins and the world is loaded. */ /** Called when a game begins and the world is loaded. */
public static class WorldLoadEvent{} public static class WorldLoadEvent{}

View File

@@ -31,7 +31,6 @@ public enum Gamemode{
rules.buildCostMultiplier = 1f; rules.buildCostMultiplier = 1f;
rules.buildSpeedMultiplier = 1f; rules.buildSpeedMultiplier = 1f;
rules.unitBuildSpeedMultiplier = 2f; rules.unitBuildSpeedMultiplier = 2f;
rules.unitHealthMultiplier = 3f;
rules.attackMode = true; rules.attackMode = true;
}, map -> map.teams.size > 1), }, map -> map.teams.size > 1),
editor(true, rules -> { editor(true, rules -> {

View File

@@ -44,10 +44,10 @@ public class Rules{
public boolean fire = true; public boolean fire = true;
/** Whether units use and require ammo. */ /** Whether units use and require ammo. */
public boolean unitAmmo = false; public boolean unitAmmo = false;
/** Whether cores add to unit limit */
public boolean unitCapVariable = true;
/** How fast unit pads build units. */ /** How fast unit pads build units. */
public float unitBuildSpeedMultiplier = 1f; public float unitBuildSpeedMultiplier = 1f;
/** How much health units start with. */
public float unitHealthMultiplier = 1f;
/** How much damage any other units deal. */ /** How much damage any other units deal. */
public float unitDamageMultiplier = 1f; public float unitDamageMultiplier = 1f;
/** How much health blocks start with. */ /** How much health blocks start with. */
@@ -65,7 +65,7 @@ public class Rules{
/** Radius around enemy wave drop zones.*/ /** Radius around enemy wave drop zones.*/
public float dropZoneRadius = 300f; public float dropZoneRadius = 300f;
/** Time between waves in ticks. */ /** Time between waves in ticks. */
public float waveSpacing = 60 * 60 * 2; public float waveSpacing = 2 * Time.toMinutes;
/** Wave after which the player 'wins'. Used in sectors. Use a value <= 0 to disable. */ /** Wave after which the player 'wins'. Used in sectors. Use a value <= 0 to disable. */
public int winWave = 0; public int winWave = 0;
/** Base unit cap. Can still be increased by blocks. */ /** Base unit cap. Can still be increased by blocks. */
@@ -139,7 +139,7 @@ public class Rules{
} }
/** A simple map for storing TeamRules in an efficient way without hashing. */ /** A simple map for storing TeamRules in an efficient way without hashing. */
public static class TeamRules implements Serializable{ public static class TeamRules implements JsonSerializable{
final TeamRule[] values = new TeamRule[Team.all.length]; final TeamRule[] values = new TeamRule[Team.all.length];
public TeamRule get(Team team){ public TeamRule get(Team team){

View File

@@ -285,7 +285,7 @@ public class Schematics implements Loadable{
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */ /** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
public Seq<BuildPlan> toRequests(Schematic schem, int x, int y){ public Seq<BuildPlan> toRequests(Schematic schem, int x, int y){
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block, t.config).original(t.x, t.y, schem.width, schem.height)) return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block, t.config).original(t.x, t.y, schem.width, schem.height))
.removeAll(s -> (!s.block.isVisible() && !(s.block instanceof CoreBlock)) || !s.block.unlockedNow()); .removeAll(s -> (!s.block.isVisible() && !(s.block instanceof CoreBlock)) || !s.block.unlockedNow()).sort(Structs.comparingInt(s -> -s.block.schematicPriority));
} }
/** @return all the valid loadouts for a specific core type. */ /** @return all the valid loadouts for a specific core type. */

View File

@@ -18,7 +18,7 @@ import static mindustry.Vars.*;
* weapon equipped, ammo used, and status effects. * weapon equipped, ammo used, and status effects.
* Each spawn group can have multiple sub-groups spawned in different areas of the map. * Each spawn group can have multiple sub-groups spawned in different areas of the map.
*/ */
public class SpawnGroup implements Serializable{ public class SpawnGroup implements JsonSerializable{
public static final int never = Integer.MAX_VALUE; public static final int never = Integer.MAX_VALUE;
/** The unit type spawned */ /** The unit type spawned */

View File

@@ -123,6 +123,7 @@ public class Universe{
} }
/** @return the last selected loadout for this specific core type. */ /** @return the last selected loadout for this specific core type. */
@Nullable
public Schematic getLoadout(CoreBlock core){ public Schematic getLoadout(CoreBlock core){
//for tools - schem //for tools - schem
if(schematics == null) return Loadouts.basicShard; if(schematics == null) return Loadouts.basicShard;
@@ -134,7 +135,7 @@ public class Universe{
Seq<Schematic> all = schematics.getLoadouts(core); Seq<Schematic> all = schematics.getLoadouts(core);
Schematic schem = all.find(s -> s.file != null && s.file.nameWithoutExtension().equals(file)); Schematic schem = all.find(s -> s.file != null && s.file.nameWithoutExtension().equals(file));
return schem == null ? all.first() : schem; return schem == null ? all.any() ? all.first() : null : schem;
} }
/** Runs possible events. Resets event counter. */ /** Runs possible events. Resets event counter. */

View File

@@ -221,9 +221,13 @@ public class Drawf{
} }
public static void construct(float x, float y, TextureRegion region, float rotation, float progress, float speed, float time){ public static void construct(float x, float y, TextureRegion region, float rotation, float progress, float speed, float time){
construct(x, y, region, Pal.accent, rotation, progress, speed, time);
}
public static void construct(float x, float y, TextureRegion region, Color color, float rotation, float progress, float speed, float time){
Shaders.build.region = region; Shaders.build.region = region;
Shaders.build.progress = progress; Shaders.build.progress = progress;
Shaders.build.color.set(Pal.accent); Shaders.build.color.set(color);
Shaders.build.color.a = speed; Shaders.build.color.a = speed;
Shaders.build.time = -time / 20f; Shaders.build.time = -time / 20f;
@@ -235,9 +239,13 @@ public class Drawf{
} }
public static void construct(Building t, TextureRegion region, float rotation, float progress, float speed, float time){ public static void construct(Building t, TextureRegion region, float rotation, float progress, float speed, float time){
construct(t, region, Pal.accent, rotation, progress, speed, time);
}
public static void construct(Building t, TextureRegion region, Color color, float rotation, float progress, float speed, float time){
Shaders.build.region = region; Shaders.build.region = region;
Shaders.build.progress = progress; Shaders.build.progress = progress;
Shaders.build.color.set(Pal.accent); Shaders.build.color.set(color);
Shaders.build.color.a = speed; Shaders.build.color.a = speed;
Shaders.build.time = -time / 20f; Shaders.build.time = -time / 20f;

View File

@@ -119,6 +119,7 @@ public class FloorRenderer implements Disposable{
return; return;
} }
Draw.flush();
cbatch.setProjection(Core.camera.mat); cbatch.setProjection(Core.camera.mat);
cbatch.beginDraw(); cbatch.beginDraw();

View File

@@ -54,7 +54,7 @@ public class LoadRenderer implements Disposable{
bars = new Bar[]{ bars = new Bar[]{
new Bar("s_proc#", OS.cores / 16f, OS.cores < 4), new Bar("s_proc#", OS.cores / 16f, OS.cores < 4),
new Bar("c_aprog", () -> assets != null, () -> assets.getProgress(), () -> false), new Bar("c_aprog", () -> assets != null, () -> assets.getProgress(), () -> false),
new Bar("g_vtype", graphics.getGLVersion().type == Type.GLES ? 0.5f : 1f, graphics.getGLVersion().type == Type.GLES), new Bar("g_vtype", graphics.getGLVersion().type == GlType.GLES ? 0.5f : 1f, graphics.getGLVersion().type == GlType.GLES),
new Bar("s_mem#", () -> true, () -> Core.app.getJavaHeap() / 1024f / 1024f / 200f, () -> Core.app.getJavaHeap() > 1024 * 1024 * 110), new Bar("s_mem#", () -> true, () -> Core.app.getJavaHeap() / 1024f / 1024f / 200f, () -> Core.app.getJavaHeap() > 1024 * 1024 * 110),
new Bar("v_ver#", () -> Version.build != 0, () -> Version.build == -1 ? 0.3f : (Version.build - 103f) / 10f, () -> !Version.modifier.equals("release")), new Bar("v_ver#", () -> Version.build != 0, () -> Version.build == -1 ? 0.3f : (Version.build - 103f) / 10f, () -> !Version.modifier.equals("release")),
new Bar("s_osv", OS.isWindows ? 0.35f : OS.isLinux ? 0.9f : OS.isMac ? 0.5f : 0.2f, OS.isMac), new Bar("s_osv", OS.isWindows ? 0.35f : OS.isLinux ? 0.9f : OS.isMac ? 0.5f : 0.2f, OS.isMac),

View File

@@ -96,7 +96,8 @@ public class MinimapRenderer implements Disposable{
Draw.mixcol(unit.team().color, 1f); Draw.mixcol(unit.team().color, 1f);
float scale = Scl.scl(1f) / 2f * scaling * 32f; float scale = Scl.scl(1f) / 2f * scaling * 32f;
Draw.rect(unit.type.icon(Cicon.full), x + rx, y + ry, scale, scale, unit.rotation() - 90); var region = unit.type.icon(Cicon.full);
Draw.rect(region, x + rx, y + ry, scale, scale * (float)region.height / region.width, unit.rotation() - 90);
Draw.reset(); Draw.reset();
} }

View File

@@ -15,10 +15,10 @@ import mindustry.type.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class Shaders{ public class Shaders{
public static BlockBuild blockbuild; public static BlockBuildShader blockbuild;
public static @Nullable ShieldShader shield; public static @Nullable ShieldShader shield;
public static BuildBeamShader buildBeam; public static BuildBeamShader buildBeam;
public static UnitBuild build; public static UnitBuildShader build;
public static DarknessShader darkness; public static DarknessShader darkness;
public static LightShader light; public static LightShader light;
public static SurfaceShader water, mud, tar, slag, space; public static SurfaceShader water, mud, tar, slag, space;
@@ -31,7 +31,7 @@ public class Shaders{
public static void init(){ public static void init(){
mesh = new MeshShader(); mesh = new MeshShader();
blockbuild = new BlockBuild(); blockbuild = new BlockBuildShader();
try{ try{
shield = new ShieldShader(); shield = new ShieldShader();
}catch(Throwable t){ }catch(Throwable t){
@@ -40,7 +40,7 @@ public class Shaders{
t.printStackTrace(); t.printStackTrace();
} }
buildBeam = new BuildBeamShader(); buildBeam = new BuildBeamShader();
build = new UnitBuild(); build = new UnitBuildShader();
darkness = new DarknessShader(); darkness = new DarknessShader();
light = new LightShader(); light = new LightShader();
water = new SurfaceShader("water"); water = new SurfaceShader("water");
@@ -142,12 +142,16 @@ public class Shaders{
} }
} }
public static class UnitBuild extends LoadShader{ /** @deprecated transition class for mods; use UnitBuildShader instead. */
@Deprecated
public static class UnitBuild extends UnitBuildShader{}
public static class UnitBuildShader extends LoadShader{
public float progress, time; public float progress, time;
public Color color = new Color(); public Color color = new Color();
public TextureRegion region; public TextureRegion region;
public UnitBuild(){ public UnitBuildShader(){
super("unitbuild", "default"); super("unitbuild", "default");
} }
@@ -162,11 +166,11 @@ public class Shaders{
} }
} }
public static class BlockBuild extends LoadShader{ public static class BlockBuildShader extends LoadShader{
public float progress; public float progress;
public TextureRegion region = new TextureRegion(); public TextureRegion region = new TextureRegion();
public BlockBuild(){ public BlockBuildShader(){
super("blockbuild", "default"); super("blockbuild", "default");
} }

View File

@@ -8,7 +8,6 @@ import arc.graphics.g2d.*;
import arc.math.*; import arc.math.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.scene.*; import arc.scene.*;
import arc.scene.event.*;
import arc.scene.ui.*; import arc.scene.ui.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.*; import arc.util.*;
@@ -46,34 +45,36 @@ public class DesktopInput extends InputHandler{
/** Mouse pan speed. */ /** Mouse pan speed. */
public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f; public float panScale = 0.005f, panSpeed = 4.5f, panBoostSpeed = 11f;
boolean showHint(){
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() &&
(!isBuilding && !Core.settings.getBool("buildautopause") || player.unit().isBuilding() || !player.dead() && !player.unit().spawnedByCore());
}
@Override @Override
public void buildUI(Group group){ public void buildUI(Group group){
//respawn hints //building and respawn hints
group.fill(t -> { group.fill(t -> {
t.visible(() -> Core.settings.getBool("hints") && ui.hudfrag.shown && !player.dead() && !player.unit().spawnedByCore() && !(Core.settings.getBool("hints") && lastSchematic != null && !selectRequests.isEmpty())); t.color.a = 0f;
t.visible(() -> (t.color.a = Mathf.lerpDelta(t.color.a, Mathf.num(showHint()), 0.15f)) > 0.001f);
t.bottom(); t.bottom();
t.table(Styles.black6, b -> { t.table(Styles.black6, b -> {
StringBuilder str = new StringBuilder();
b.defaults().left(); b.defaults().left();
b.label(() -> Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString())).style(Styles.outlineLabel); b.label(() -> {
}).margin(6f); if(!showHint()) return str;
}); str.setLength(0);
if(!isBuilding && !Core.settings.getBool("buildautopause") && !player.unit().isBuilding()){
//building hints str.append(Core.bundle.format("enablebuilding", Core.keybinds.get(Binding.pause_building).key.toString()));
group.fill(t -> { }else if(player.unit().isBuilding()){
t.bottom(); str.append(Core.bundle.format(isBuilding ? "pausebuilding" : "resumebuilding", Core.keybinds.get(Binding.pause_building).key.toString()))
t.visible(() -> { .append("\n").append(Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString()))
t.color.a = Mathf.lerpDelta(t.color.a, player.unit().isBuilding() ? 1f : 0f, 0.15f); .append("\n").append(Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString()));
}
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectRequests.isEmpty() && t.color.a > 0.01f; if(!player.dead() && !player.unit().spawnedByCore()){
}); str.append(str.length() != 0 ? "\n" : "").append(Core.bundle.format("respawn", Core.keybinds.get(Binding.respawn).key.toString()));
t.touchable(() -> t.color.a < 0.1f ? Touchable.disabled : Touchable.childrenOnly); }
t.table(Styles.black6, b -> { return str;
b.defaults().left(); }).style(Styles.outlineLabel);
b.label(() -> Core.bundle.format(!isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.toString())).style(Styles.outlineLabel);
b.row();
b.label(() -> Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())).style(Styles.outlineLabel);
b.row();
b.label(() -> Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())).style(Styles.outlineLabel);
}).margin(10f); }).margin(10f);
}); });
@@ -204,7 +205,6 @@ public class DesktopInput extends InputHandler{
if(input.keyDown(Binding.mouse_move)){ if(input.keyDown(Binding.mouse_move)){
panCam = true; panCam = true;
} }
panning = false;
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(camSpeed)); Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(camSpeed));
}else if(!player.dead() && !panning){ }else if(!player.dead() && !panning){

View File

@@ -68,6 +68,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public Seq<BuildPlan> lineRequests = new Seq<>(); public Seq<BuildPlan> lineRequests = new Seq<>();
public Seq<BuildPlan> selectRequests = new Seq<>(); public Seq<BuildPlan> selectRequests = new Seq<>();
public InputHandler(){
Events.on(UnitDestroyEvent.class, e -> {
if(e.unit != null && e.unit.isPlayer() && e.unit.getPlayer().isLocal() && e.unit.type.weapons.contains(w -> w.bullet.killShooter)){
player.shooting = false;
}
});
}
//methods to override //methods to override
@Remote(called = Loc.server, unreliable = true) @Remote(called = Loc.server, unreliable = true)

View File

@@ -100,7 +100,7 @@ public class Placement{
i ++; i ++;
} }
if(!addedLast) result.add(base.peek()); if(!addedLast && !base.isEmpty()) result.add(base.peek());
points.clear(); points.clear();
points.addAll(result); points.addAll(result);

View File

@@ -13,8 +13,9 @@ import java.io.*;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class JsonIO{ public class JsonIO{
private static CustomJson jsonBase = new CustomJson(); private static final CustomJson jsonBase = new CustomJson();
private static Json json = new Json(){
public static final Json json = new Json(){
{ apply(this); } { apply(this); }
@Override @Override
@@ -39,10 +40,6 @@ public class JsonIO{
} }
}; };
public static Json json(){
return json;
}
public static String write(Object object){ public static String write(Object object){
return json.toJson(object, object.getClass()); return json.toJson(object, object.getClass());
} }
@@ -69,7 +66,6 @@ public class JsonIO{
} }
static void apply(Json json){ static void apply(Json json){
json.setIgnoreUnknownFields(true);
json.setElementType(Rules.class, "spawns", SpawnGroup.class); json.setElementType(Rules.class, "spawns", SpawnGroup.class);
json.setElementType(Rules.class, "loadout", ItemStack.class); json.setElementType(Rules.class, "loadout", ItemStack.class);

View File

@@ -7,6 +7,7 @@ public enum ConditionOp{
lessThanEq("<=", (a, b) -> a <= b), lessThanEq("<=", (a, b) -> a <= b),
greaterThan(">", (a, b) -> a > b), greaterThan(">", (a, b) -> a > b),
greaterThanEq(">=", (a, b) -> a >= b), greaterThanEq(">=", (a, b) -> a >= b),
strictEqual("===", (a, b) -> false),
always("always", (a, b) -> true); always("always", (a, b) -> true);
public static final ConditionOp[] all = values(); public static final ConditionOp[] all = values();

View File

@@ -21,11 +21,13 @@ public enum LAccess{
maxHealth, maxHealth,
heat, heat,
efficiency, efficiency,
timescale,
rotation, rotation,
x, x,
y, y,
shootX, shootX,
shootY, shootY,
range,
shooting, shooting,
mineX, mineX,
mineY, mineY,
@@ -44,7 +46,8 @@ public enum LAccess{
enabled("to"), //"to" is standard for single parameter access enabled("to"), //"to" is standard for single parameter access
shoot("x", "y", "shoot"), shoot("x", "y", "shoot"),
shootp(true, "unit", "shoot"), shootp(true, "unit", "shoot"),
configure(true, 30, "to"); configure(true, 30, "to"),
color("r", "g", "b");
public final String[] params; public final String[] params;
public final boolean isObj; public final boolean isObj;

View File

@@ -13,6 +13,11 @@ 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 = 36; public static final int maxTokenLength = 36;
private static final StringMap opNameChanges = StringMap.of(
"atan2", "angle",
"dst", "len"
);
private int lastVar; private int lastVar;
/** Maps names to variable IDs. */ /** Maps names to variable IDs. */
public ObjectMap<String, BVar> vars = new ObjectMap<>(); public ObjectMap<String, BVar> vars = new ObjectMap<>();
@@ -28,6 +33,8 @@ public class LAssembler{
putConst("@unit", null); putConst("@unit", null);
//reference to self //reference to self
putConst("@this", null); putConst("@this", null);
//global tick
putConst("@tick", 0);
} }
public static LAssembler assemble(String data, int maxInstructions){ public static LAssembler assemble(String data, int maxInstructions){
@@ -61,9 +68,6 @@ public class LAssembler{
String[] lines = data.split("\n"); String[] lines = data.split("\n");
int index = 0; int index = 0;
for(String line : lines){ for(String line : lines){
//comments
int commentIdx = line.indexOf('#');
if(commentIdx != -1) line = line.substring(0, commentIdx).trim();
if(line.isEmpty()) continue; if(line.isEmpty()) continue;
//remove trailing semicolons in case someone adds them in for no reason //remove trailing semicolons in case someone adds them in for no reason
if(line.endsWith(";")) line = line.substring(0, line.length() - 1); if(line.endsWith(";")) line = line.substring(0, line.length() - 1);
@@ -74,6 +78,7 @@ public class LAssembler{
try{ try{
String[] arr; String[] arr;
if(line.startsWith("#")) continue;
//yes, I am aware that this can be split with regex, but that's slow and even more incomprehensible //yes, I am aware that this can be split with regex, but that's slow and even more incomprehensible
if(line.contains(" ")){ if(line.contains(" ")){
@@ -83,7 +88,9 @@ public class LAssembler{
for(int i = 0; i < line.length() + 1; i++){ for(int i = 0; i < line.length() + 1; i++){
char c = i == line.length() ? ' ' : line.charAt(i); char c = i == line.length() ? ' ' : line.charAt(i);
if(c == '"'){ if(c == '#' && !inString){
break;
}else if(c == '"'){
inString = !inString; inString = !inString;
}else if(c == ' ' && !inString){ }else if(c == ' ' && !inString){
tokens.add(line.substring(lastIdx, Math.min(i, lastIdx + maxTokenLength))); tokens.add(line.substring(lastIdx, Math.min(i, lastIdx + maxTokenLength)));
@@ -96,6 +103,9 @@ public class LAssembler{
arr = new String[]{line}; arr = new String[]{line};
} }
//nothing found
if(arr.length == 0) continue;
String type = arr[0]; String type = arr[0];
//legacy stuff //legacy stuff
@@ -122,6 +132,11 @@ public class LAssembler{
} }
} }
//fix up changed operaiton names
if(type.equals("op")){
arr[1] = opNameChanges.get(arr[1], arr[1]);
}
LStatement st = LogicIO.read(arr); LStatement st = LogicIO.read(arr);
if(st != null){ if(st != null){

View File

@@ -41,6 +41,13 @@ public class LCanvas extends Table{
return Core.graphics.getWidth() < Scl.scl(900f) * 1.2f; return Core.graphics.getWidth() < Scl.scl(900f) * 1.2f;
} }
public static void tooltip(Cell<?> cell, String key){
String lkey = key.toLowerCase().replace(" ", "");
if(Core.settings.getBool("logichints", true) && Core.bundle.has(lkey)){
cell.get().addListener(new Tooltip(t -> t.background(Styles.black8).margin(4f).add("[lightgray]" + Core.bundle.get(lkey)).style(Styles.outlineLabel)));
}
}
public void rebuild(){ public void rebuild(){
targetWidth = useRows() ? 400f : 900f; targetWidth = useRows() ? 400f : 900f;
float s = pane != null ? pane.getScrollPercentY() : 0f; float s = pane != null ? pane.getScrollPercentY() : 0f;
@@ -283,13 +290,13 @@ public class LCanvas extends Table{
t.add().growX(); t.add().growX();
t.button(Icon.copy, Styles.logici, () -> { t.button(Icon.copy, Styles.logici, () -> {
}).padRight(6).get().tapped(this::copy); }).size(24f).padRight(6).get().tapped(this::copy);
t.button(Icon.cancel, Styles.logici, () -> { t.button(Icon.cancel, Styles.logici, () -> {
remove(); remove();
dragging = null; dragging = null;
statements.layout(); statements.layout();
}); }).size(24f);
t.addListener(new InputListener(){ t.addListener(new InputListener(){
float lastx, lasty; float lastx, lasty;

View File

@@ -1,5 +1,6 @@
package mindustry.logic; package mindustry.logic;
import arc.*;
import arc.math.geom.*; import arc.math.geom.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
@@ -35,7 +36,8 @@ public class LExecutor{
varCounter = 0, varCounter = 0,
varTime = 1, varTime = 1,
varUnit = 2, varUnit = 2,
varThis = 3; varThis = 3,
varTick = 4;
public static final int public static final int
maxGraphicsBuffer = 256, maxGraphicsBuffer = 256,
@@ -60,6 +62,7 @@ public class LExecutor{
public void runOnce(){ public void runOnce(){
//set time //set time
vars[varTime].numval = Time.millis(); vars[varTime].numval = Time.millis();
vars[varTick].numval = Time.time;
//reset to start //reset to start
if(vars[varCounter].numval >= instructions.length || vars[varCounter].numval < 0){ if(vars[varCounter].numval >= instructions.length || vars[varCounter].numval < 0){
@@ -98,6 +101,10 @@ public class LExecutor{
//region utility //region utility
private static boolean invalid(double d){
return Double.isNaN(d) || Double.isInfinite(d);
}
public Var var(int index){ public Var var(int index){
//global constants have variable IDs < 0, and they are fetched from the global constants object after being negated //global constants have variable IDs < 0, and they are fetched from the global constants object after being negated
return index < 0 ? constants.get(-index) : vars[index]; return index < 0 ? constants.get(-index) : vars[index];
@@ -120,12 +127,12 @@ public class LExecutor{
public double num(int index){ public double num(int index){
Var v = var(index); Var v = var(index);
return v.isobj ? v.objval != null ? 1 : 0 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : v.numval; return v.isobj ? v.objval != null ? 1 : 0 : invalid(v.numval) ? 0 : v.numval;
} }
public float numf(int index){ public float numf(int index){
Var v = var(index); Var v = var(index);
return v.isobj ? v.objval != null ? 1 : 0 : Double.isNaN(v.numval) || Double.isInfinite(v.numval) ? 0 : (float)v.numval; return v.isobj ? v.objval != null ? 1 : 0 : invalid(v.numval) ? 0 : (float)v.numval;
} }
public int numi(int index){ public int numi(int index){
@@ -139,10 +146,15 @@ public class LExecutor{
public void setnum(int index, double value){ public void setnum(int index, double value){
Var v = var(index); Var v = var(index);
if(v.constant) return; if(v.constant) return;
v.numval = Double.isNaN(value) || Double.isInfinite(value) ? 0 : value; if(invalid(value)){
v.objval = null;
v.isobj = true;
}else{
v.numval = value;
v.objval = null; v.objval = null;
v.isobj = false; v.isobj = false;
} }
}
public void setobj(int index, Object value){ public void setobj(int index, Object value){
Var v = var(index); Var v = var(index);
@@ -326,17 +338,19 @@ public class LExecutor{
@Nullable @Nullable
public static LogicAI checkLogicAI(LExecutor exec, Object unitObj){ public static LogicAI checkLogicAI(LExecutor exec, Object unitObj){
if(unitObj instanceof Unit unit && exec.obj(varUnit) == unit && unit.team == exec.team && !unit.isPlayer() && !(unit.controller() instanceof FormationAI)){ if(unitObj instanceof Unit unit && exec.obj(varUnit) == unit && unit.team == exec.team && !unit.isPlayer() && !(unit.controller() instanceof FormationAI)){
if(!(unit.controller() instanceof LogicAI)){ if(unit.controller() instanceof LogicAI la){
unit.controller(new LogicAI()); return la;
((LogicAI)unit.controller()).controller = exec.building(varThis); }else{
var la = new LogicAI();
la.controller = exec.building(varThis);
unit.controller(la);
//clear old state //clear old state
unit.mineTile = null; unit.mineTile = null;
unit.clearBuilding(); unit.clearBuilding();
return (LogicAI)unit.controller(); return la;
} }
return (LogicAI)unit.controller();
} }
return null; return null;
} }
@@ -434,7 +448,7 @@ public class LExecutor{
} }
case build -> { case build -> {
if(unit.canBuild() && 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 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize);
int rot = exec.numi(p4); int rot = exec.numi(p4);
//reset state of last request when necessary //reset state of last request when necessary
@@ -622,21 +636,21 @@ public class LExecutor{
//note that remote units/buildings can be sensed as well //note that remote units/buildings can be sensed as well
if(target instanceof Senseable se){ if(target instanceof Senseable se){
if(sense instanceof Content){ if(sense instanceof Content co){
exec.setnum(to, se.sense(((Content)sense))); exec.setnum(to, se.sense(co));
}else if(sense instanceof LAccess){ }else if(sense instanceof LAccess la){
Object objOut = se.senseObject((LAccess)sense); Object objOut = se.senseObject(la);
if(objOut == Senseable.noSensed){ if(objOut == Senseable.noSensed){
//numeric output //numeric output
exec.setnum(to, se.sense((LAccess)sense)); exec.setnum(to, se.sense(la));
}else{ }else{
//object output //object output
exec.setobj(to, objOut); exec.setobj(to, objOut);
} }
} }
}else{ }else{
exec.setnum(to, 0); exec.setobj(to, null);
} }
} }
} }
@@ -752,7 +766,7 @@ public class LExecutor{
v.objval = f.objval; v.objval = f.objval;
v.isobj = true; v.isobj = true;
}else{ }else{
v.numval = Double.isNaN(f.numval) || Double.isInfinite(f.numval) ? 0 : f.numval; v.numval = invalid(f.numval) ? 0 : f.numval;
v.isobj = false; v.isobj = false;
} }
} }
@@ -774,14 +788,17 @@ public class LExecutor{
@Override @Override
public void run(LExecutor exec){ public void run(LExecutor exec){
if(op.unary){ if(op == LogicOp.strictEqual){
Var v = exec.var(a), v2 = exec.var(b);
exec.setnum(dest, v.isobj == v2.isobj && ((v.isobj && v.objval == v2.objval) || (!v.isobj && v.numval == v2.numval)) ? 1 : 0);
}else if(op.unary){
exec.setnum(dest, op.function1.get(exec.num(a))); exec.setnum(dest, op.function1.get(exec.num(a)));
}else{ }else{
Var va = exec.var(a); Var va = exec.var(a);
Var vb = exec.var(b); Var vb = exec.var(b);
if(op.objFunction2 != null && va.isobj && vb.isobj){ if(op.objFunction2 != null && va.isobj && vb.isobj){
//use object function if provided, and one of the variables is an object //use object function if both are objects
exec.setnum(dest, op.objFunction2.get(exec.obj(a), exec.obj(b))); exec.setnum(dest, op.objFunction2.get(exec.obj(a), exec.obj(b)));
}else{ }else{
//otherwise use the numeric function //otherwise use the numeric function
@@ -888,6 +905,7 @@ public class LExecutor{
String strValue = String strValue =
v.objval == null ? "null" : v.objval == null ? "null" :
v.objval instanceof String s ? s : v.objval instanceof String s ? s :
v.objval == Blocks.stoneWall ? "solid" : //special alias
v.objval instanceof MappableContent content ? content.name : v.objval instanceof MappableContent content ? content.name :
v.objval instanceof Content ? "[content]" : v.objval instanceof Content ? "[content]" :
v.objval instanceof Building build ? build.block.name : v.objval instanceof Building build ? build.block.name :
@@ -950,8 +968,10 @@ public class LExecutor{
Var vb = exec.var(compare); Var vb = exec.var(compare);
boolean cmp; boolean cmp;
if(op.objFunction != null && va.isobj && vb.isobj){ if(op == ConditionOp.strictEqual){
//use object function if provided, and one of the variables is an object cmp = va.isobj == vb.isobj && ((va.isobj && va.objval == vb.objval) || (!va.isobj && va.numval == vb.numval));
}else if(op.objFunction != null && va.isobj && vb.isobj){
//use object function if both are objects
cmp = op.objFunction.get(exec.obj(value), exec.obj(compare)); cmp = op.objFunction.get(exec.obj(value), exec.obj(compare));
}else{ }else{
cmp = op.function.get(exec.num(value), exec.num(compare)); cmp = op.function.get(exec.num(value), exec.num(compare));
@@ -964,5 +984,37 @@ public class LExecutor{
} }
} }
public static class WaitI implements LInstruction{
public int value;
public float curTime;
public double wait;
public long frameId;
public WaitI(int value){
this.value = value;
}
public WaitI(){
}
@Override
public void run(LExecutor exec){
if(curTime >= exec.num(value)){
curTime = 0f;
}else{
//skip back to self.
exec.var(varCounter).numval --;
}
if(Core.graphics.getFrameId() != frameId){
curTime += Time.delta / 60f;
frameId = Core.graphics.getFrameId();
}
}
}
//endregion //endregion
} }

View File

@@ -15,6 +15,8 @@ import mindustry.logic.LCanvas.*;
import mindustry.logic.LExecutor.*; import mindustry.logic.LExecutor.*;
import mindustry.ui.*; import mindustry.ui.*;
import static mindustry.logic.LCanvas.*;
/** /**
* A statement is an intermediate representation of an instruction, to be used mostly in UI. * A statement is an intermediate representation of an instruction, to be used mostly in UI.
* Contains all relevant variable information. */ * Contains all relevant variable information. */
@@ -38,13 +40,18 @@ public abstract class LStatement{
//protected methods are only for internal UI layout utilities //protected methods are only for internal UI layout utilities
protected void param(Cell<Label> label){
String text = name() + "." + label.get().getText().toString().trim();
tooltip(label, text);
}
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).maxTextLength(LAssembler.maxTokenLength).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){
table.add(desc).padLeft(10).left(); table.add(desc).padLeft(10).left().self(this::param);;
return field(table, value, setter).width(85f).padRight(10).left(); return field(table, value, setter).width(85f).padRight(10).left();
} }
@@ -58,29 +65,40 @@ public abstract class LStatement{
} }
} }
protected <T> void showSelect(Button b, T[] values, T current, Cons<T> getter, int cols, Cons<Cell> sizer){ protected <T extends Enum<T>> void showSelect(Button b, T[] values, T current, Cons<T> getter, int cols, Cons<Cell> sizer){
showSelectTable(b, (t, hide) -> { showSelectTable(b, (t, hide) -> {
ButtonGroup<Button> group = new ButtonGroup<>(); ButtonGroup<Button> group = new ButtonGroup<>();
int i = 0; int i = 0;
t.defaults().size(56f, 40f); t.defaults().size(60f, 38f);
for(T p : values){ for(T p : values){
sizer.get(t.button(p.toString(), Styles.clearTogglet, () -> { sizer.get(t.button(p.toString(), Styles.logicTogglet, () -> {
getter.get(p); getter.get(p);
hide.run(); hide.run();
}).checked(current == p).group(group)); }).self(c -> tooltip(c, "lenum." + p.name())).checked(current == p).group(group));
if(++i % cols == 0) t.row(); if(++i % cols == 0) t.row();
} }
}); });
} }
protected <T> void showSelect(Button b, T[] values, T current, Cons<T> getter){ protected <T extends Enum<T>> void showSelect(Button b, T[] values, T current, Cons<T> getter){
showSelect(b, values, current, getter, 4, c -> {}); showSelect(b, values, current, getter, 4, c -> {});
} }
protected void showSelectTable(Button b, Cons2<Table, Runnable> hideCons){ protected void showSelectTable(Button b, Cons2<Table, Runnable> hideCons){
Table t = new Table(Tex.button); Table t = new Table(Tex.paneSolid){
@Override
public float getPrefHeight(){
return Math.min(super.getPrefHeight(), Core.graphics.getHeight());
}
@Override
public float getPrefWidth(){
return Math.min(super.getPrefWidth(), Core.graphics.getWidth());
}
};
t.margin(4);
//triggers events behind the element to simulate deselection //triggers events behind the element to simulate deselection
Element hitter = new Element(); Element hitter = new Element();
@@ -110,14 +128,15 @@ public abstract class LStatement{
if(t.getWidth() > Core.scene.getWidth()) t.setWidth(Core.graphics.getWidth()); if(t.getWidth() > Core.scene.getWidth()) t.setWidth(Core.graphics.getWidth());
if(t.getHeight() > Core.scene.getHeight()) t.setHeight(Core.graphics.getHeight()); if(t.getHeight() > Core.scene.getHeight()) t.setHeight(Core.graphics.getHeight());
t.keepInStage(); t.keepInStage();
t.invalidateHierarchy();
t.pack();
}); });
t.actions(Actions.alpha(0), Actions.fadeIn(0.3f, Interp.fade)); t.actions(Actions.alpha(0), Actions.fadeIn(0.3f, Interp.fade));
t.top().pane(inner -> { t.top().pane(inner -> {
inner.marginRight(24f);
inner.top(); inner.top();
hideCons.get(inner, hide); hideCons.get(inner, hide);
}).top(); }).pad(0f).top().get().setScrollingDisabled(true, false);
t.pack(); t.pack();
} }
@@ -139,4 +158,5 @@ public abstract class LStatement{
public String name(){ public String name(){
return Strings.insertSpaces(getClass().getSimpleName().replace("Statement", "")); return Strings.insertSpaces(getClass().getSimpleName().replace("Statement", ""));
} }
} }

View File

@@ -15,6 +15,7 @@ import mindustry.type.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.logic.LCanvas.*;
import static mindustry.world.blocks.logic.LogicDisplay.*; import static mindustry.world.blocks.logic.LogicDisplay.*;
public class LStatements{ public class LStatements{
@@ -355,7 +356,7 @@ public class LStatements{
}, 2, cell -> cell.size(100, 50))); }, 2, cell -> cell.size(100, 50)));
}, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2); }, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2);
table.add(" of "); table.add(" of ").self(this::param);
field(table, target, v -> target = v); field(table, target, v -> target = v);
@@ -394,7 +395,7 @@ public class LStatements{
table.defaults().left(); table.defaults().left();
if(buildFrom()){ if(buildFrom()){
table.add(" from "); table.add(" from ").self(this::param);
fields(table, radar, v -> radar = v); fields(table, radar, v -> radar = v);
@@ -405,7 +406,7 @@ public class LStatements{
int fi = i; int fi = i;
Prov<RadarTarget> get = () -> (fi == 0 ? target1 : fi == 1 ? target2 : target3); Prov<RadarTarget> get = () -> (fi == 0 ? target1 : fi == 1 ? target2 : target3);
table.add(i == 0 ? " target " : " and "); table.add(i == 0 ? " target " : " and ").self(this::param);
table.button(b -> { table.button(b -> {
b.label(() -> get.get().name()); b.label(() -> get.get().name());
@@ -419,13 +420,13 @@ public class LStatements{
} }
} }
table.add(" order "); table.add(" order ").self(this::param);
fields(table, sortOrder, v -> sortOrder = v); fields(table, sortOrder, v -> sortOrder = v);
table.row(); table.row();
table.add(" sort "); table.add(" sort ").self(this::param);
table.button(b -> { table.button(b -> {
b.label(() -> sort.name()); b.label(() -> sort.name());
@@ -434,7 +435,7 @@ public class LStatements{
}, 2, cell -> cell.size(100, 50))); }, 2, cell -> cell.size(100, 50)));
}, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2); }, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2);
table.add(" output "); table.add(" output ").self(this::param);
fields(table, output, v -> output = v); fields(table, output, v -> output = v);
} }
@@ -511,7 +512,7 @@ public class LStatements{
i.button(sensor.name(), Styles.cleart, () -> { i.button(sensor.name(), Styles.cleart, () -> {
stype("@" + sensor.name()); stype("@" + sensor.name());
hide.run(); hide.run();
}).size(240f, 40f).row(); }).size(240f, 40f).self(c -> tooltip(c, "lenum." + sensor.name())).row();
} }
}) })
}; };
@@ -531,14 +532,14 @@ public class LStatements{
t.parent.parent.pack(); t.parent.parent.pack();
t.parent.parent.invalidateHierarchy(); t.parent.parent.invalidateHierarchy();
}).size(80f, 50f).growX().checked(selected == fi).group(group); }).height(50f).growX().checked(selected == fi).group(group);
} }
t.row(); t.row();
t.add(stack).colspan(3).width(240f).left(); t.add(stack).colspan(3).width(240f).left();
})); }));
}, Styles.logict, () -> {}).size(40f).padLeft(-1).color(table.color); }, Styles.logict, () -> {}).size(40f).padLeft(-1).color(table.color);
table.add(" in "); table.add(" in ").self(this::param);
field(table, from, str -> from = str); field(table, from, str -> from = str);
} }
@@ -608,6 +609,20 @@ public class LStatements{
}else{ }else{
row(table); row(table);
//"function"-type operations have the name at the left and arguments on the right
if(op.func){
if(LCanvas.useRows()){
table.left();
table.row();
table.table(c -> {
c.color.set(color());
c.left();
funcs(c);
}).colspan(2).left();
}else{
funcs(table);
}
}else{
field(table, a, str -> a = str); field(table, a, str -> a = str);
opButton(table); opButton(table);
@@ -615,6 +630,15 @@ public class LStatements{
field(table, b, str -> b = str); field(table, b, str -> b = str);
} }
} }
}
void funcs(Table table){
opButton(table);
field(table, a, str -> a = str);
field(table, b, str -> b = str);
}
void opButton(Table table){ void opButton(Table table){
table.button(b -> { table.button(b -> {
@@ -623,7 +647,7 @@ public class LStatements{
op = o; op = o;
rebuild(table); rebuild(table);
})); }));
}, Styles.logict, () -> {}).size(60f, 40f).pad(4f).color(table.color); }, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color);
} }
@Override @Override
@@ -637,6 +661,28 @@ public class LStatements{
} }
} }
//TODO untested
//@RegisterStatement("wait")
public static class WaitStatement extends LStatement{
public String value = "0.5";
@Override
public void build(Table table){
field(table, value, str -> value = str);
table.add(" sec");
}
@Override
public Color color(){
return Pal.logicOperations;
}
@Override
public LInstruction build(LAssembler builder){
return new WaitI(builder.var(value));
}
}
@RegisterStatement("end") @RegisterStatement("end")
public static class EndStatement extends LStatement{ public static class EndStatement extends LStatement{
@Override @Override
@@ -855,7 +901,7 @@ public class LStatements{
void rebuild(Table table){ void rebuild(Table table){
table.clearChildren(); table.clearChildren();
table.add(" find ").left(); table.add(" find ").left().self(this::param);;
table.button(b -> { table.button(b -> {
b.label(() -> locate.name()); b.label(() -> locate.name());
@@ -868,14 +914,14 @@ public class LStatements{
switch(locate){ switch(locate){
case building -> { case building -> {
row(table); row(table);
table.add(" type ").left(); table.add(" group ").left().self(this::param);;
table.button(b -> { table.button(b -> {
b.label(() -> flag.name()); b.label(() -> flag.name());
b.clicked(() -> showSelect(b, BlockFlag.all, flag, t -> flag = t, 2, cell -> cell.size(110, 50))); b.clicked(() -> showSelect(b, BlockFlag.allLogic, flag, t -> flag = t, 2, cell -> cell.size(110, 50)));
}, Styles.logict, () -> {}).size(110, 40).color(table.color).left().padLeft(2); }, Styles.logict, () -> {}).size(110, 40).color(table.color).left().padLeft(2);
row(table); row(table);
table.add(" enemy ").left(); table.add(" enemy ").left().self(this::param);;
fields(table, enemy, str -> enemy = str); fields(table, enemy, str -> enemy = str);
@@ -883,7 +929,7 @@ public class LStatements{
} }
case ore -> { case ore -> {
table.add(" ore ").left(); table.add(" ore ").left().self(this::param);
table.table(ts -> { table.table(ts -> {
ts.color.set(table.color); ts.color.set(table.color);
@@ -920,19 +966,19 @@ public class LStatements{
} }
} }
table.add(" outX ").left(); table.add(" outX ").left().self(this::param);
fields(table, outX, str -> outX = str); fields(table, outX, str -> outX = str);
table.add(" outY ").left(); table.add(" outY ").left().self(this::param);
fields(table, outY, str -> outY = str); fields(table, outY, str -> outY = str);
row(table); row(table);
table.add(" found ").left(); table.add(" found ").left().self(this::param);
fields(table, outFound, str -> outFound = str); fields(table, outFound, str -> outFound = str);
if(locate != LLocate.ore){ if(locate != LLocate.ore){
table.add(" building ").left(); table.add(" building ").left().self(this::param);
fields(table, outBuild, str -> outBuild = str); fields(table, outBuild, str -> outBuild = str);
} }

View File

@@ -10,6 +10,7 @@ import mindustry.ui.*;
import mindustry.ui.dialogs.*; import mindustry.ui.dialogs.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
import static mindustry.logic.LCanvas.*;
public class LogicDialog extends BaseDialog{ public class LogicDialog extends BaseDialog{
public LCanvas canvas; public LCanvas canvas;
@@ -35,6 +36,11 @@ public class LogicDialog extends BaseDialog{
p.table(Tex.button, t -> { p.table(Tex.button, t -> {
TextButtonStyle style = Styles.cleart; TextButtonStyle style = Styles.cleart;
t.defaults().size(280f, 60f).left(); t.defaults().size(280f, 60f).left();
t.button("@schematic.copy", Icon.copy, style, () -> {
dialog.hide();
Core.app.setClipboardText(canvas.save());
}).marginLeft(12f);
t.row(); t.row();
t.button("@schematic.copy.import", Icon.download, style, () -> { t.button("@schematic.copy.import", Icon.download, style, () -> {
dialog.hide(); dialog.hide();
@@ -44,11 +50,6 @@ public class LogicDialog extends BaseDialog{
ui.showException(e); ui.showException(e);
} }
}).marginLeft(12f).disabled(b -> Core.app.getClipboardText() == null); }).marginLeft(12f).disabled(b -> Core.app.getClipboardText() == null);
t.row();
t.button("@schematic.copy", Icon.copy, style, () -> {
dialog.hide();
Core.app.setClipboardText(canvas.save());
}).marginLeft(12f);
}); });
}); });
@@ -72,7 +73,7 @@ public class LogicDialog extends BaseDialog{
t.button(example.name(), style, () -> { t.button(example.name(), style, () -> {
canvas.add(prov.get()); canvas.add(prov.get());
dialog.hide(); dialog.hide();
}).size(140f, 50f); }).size(140f, 50f).self(c -> tooltip(c, "lst." + example.name()));
if(++i % 2 == 0) t.row(); if(++i % 2 == 0) t.row();
} }
}); });

View File

@@ -19,6 +19,7 @@ public enum LogicOp{
lessThanEq("<=", (a, b) -> a <= b ? 1 : 0), lessThanEq("<=", (a, b) -> a <= b ? 1 : 0),
greaterThan(">", (a, b) -> a > b ? 1 : 0), greaterThan(">", (a, b) -> a > b ? 1 : 0),
greaterThanEq(">=", (a, b) -> a >= b ? 1 : 0), greaterThanEq(">=", (a, b) -> a >= b ? 1 : 0),
strictEqual("===", (a, b) -> 0), //this lambda is not actually used
shl("<<", (a, b) -> (long)a << (long)b), shl("<<", (a, b) -> (long)a << (long)b),
shr(">>", (a, b) -> (long)a >> (long)b), shr(">>", (a, b) -> (long)a >> (long)b),
@@ -27,11 +28,11 @@ public enum LogicOp{
xor("xor", (a, b) -> (long)a ^ (long)b), xor("xor", (a, b) -> (long)a ^ (long)b),
not("flip", a -> ~(long)(a)), not("flip", a -> ~(long)(a)),
max("max", Math::max), max("max", true, Math::max),
min("min", Math::min), min("min", true, Math::min),
atan2("atan2", (x, y) -> Mathf.atan2((float)x, (float)y) * Mathf.radDeg), angle("angle", true, (x, y) -> Angles.angle((float)x, (float)y)),
dst("dst", (x, y) -> Mathf.dst((float)x, (float)y)), len("len", true, (x, y) -> Mathf.dst((float)x, (float)y)),
noise("noise", LExecutor.noise::rawNoise2D), noise("noise", true, LExecutor.noise::rawNoise2D),
abs("abs", a -> Math.abs(a)), abs("abs", a -> Math.abs(a)),
log("log", Math::log), log("log", Math::log),
log10("log10", Math::log10), log10("log10", Math::log10),
@@ -48,19 +49,29 @@ public enum LogicOp{
public final OpObjLambda2 objFunction2; public final OpObjLambda2 objFunction2;
public final OpLambda2 function2; public final OpLambda2 function2;
public final OpLambda1 function1; public final OpLambda1 function1;
public final boolean unary; public final boolean unary, func;
public final String symbol; public final String symbol;
LogicOp(String symbol, OpLambda2 function){ LogicOp(String symbol, OpLambda2 function){
this(symbol, function, null); this(symbol, function, null);
} }
LogicOp(String symbol, boolean func, OpLambda2 function){
this.symbol = symbol;
this.function2 = function;
this.function1 = null;
this.unary = false;
this.objFunction2 = null;
this.func = func;
}
LogicOp(String symbol, OpLambda2 function, OpObjLambda2 objFunction){ LogicOp(String symbol, OpLambda2 function, OpObjLambda2 objFunction){
this.symbol = symbol; this.symbol = symbol;
this.function2 = function; this.function2 = function;
this.function1 = null; this.function1 = null;
this.unary = false; this.unary = false;
this.objFunction2 = objFunction; this.objFunction2 = objFunction;
this.func = false;
} }
LogicOp(String symbol, OpLambda1 function){ LogicOp(String symbol, OpLambda1 function){
@@ -69,6 +80,7 @@ public enum LogicOp{
this.function2 = null; this.function2 = null;
this.unary = true; this.unary = true;
this.objFunction2 = null; this.objFunction2 = null;
this.func = false;
} }
@Override @Override

View File

@@ -4,6 +4,7 @@ package mindustry.mod;
public class ModListing{ public class ModListing{
public String repo, name, author, lastUpdated, description, minGameVersion; public String repo, name, author, lastUpdated, description, minGameVersion;
public boolean hasScripts, hasJava; public boolean hasScripts, hasJava;
public String[] contentTypes = {};
public int stars; public int stars;
@Override @Override

View File

@@ -65,23 +65,39 @@ public class Mods implements Loadable{
}); });
} }
/** @return the loaded mod found by name, or null if not found. */
public @Nullable LoadedMod getMod(String name){
return mods.find(m -> m.name.equals(name));
}
/** @return the loaded mod found by class, or null if not found. */ /** @return the loaded mod found by class, or null if not found. */
public @Nullable LoadedMod getMod(Class<? extends Mod> type){ public @Nullable LoadedMod getMod(Class<? extends Mod> type){
return mods.find(m -> m.enabled() && m.main != null && m.main.getClass() == type); return mods.find(m -> m.enabled() && m.main != null && m.main.getClass() == type);
} }
/** Imports an external mod file.*/ /** Imports an external mod file. Folders are not supported here. */
public void importMod(Fi file) throws IOException{ public LoadedMod importMod(Fi file) throws IOException{
Fi dest = modDirectory.child(file.name()); String baseName = file.nameWithoutExtension();
if(dest.exists()){ String finalName = baseName;
throw new IOException("A file with the same name already exists in the mod folder!"); //find a name to prevent any name conflicts
int count = 1;
while(modDirectory.child(finalName + ".zip").exists()){
finalName = baseName + "" + count++;
} }
Fi dest = modDirectory.child(finalName + ".zip");
file.copyTo(dest); file.copyTo(dest);
try{ try{
mods.add(loadMod(dest)); var loaded = loadMod(dest, true);
mods.add(loaded);
requiresReload = true; requiresReload = true;
sortMods(); sortMods();
//try to load the mod's icon so it displays on import
Core.app.post(() -> {
loadIcon(loaded);
});
return loaded;
}catch(IOException e){ }catch(IOException e){
dest.delete(); dest.delete();
throw e; throw e;
@@ -113,16 +129,21 @@ public class Mods implements Loadable{
private void loadIcons(){ private void loadIcons(){
for(LoadedMod mod : mods){ for(LoadedMod mod : mods){
loadIcon(mod);
}
}
private void loadIcon(LoadedMod mod){
//try to load icon for each mod that can have one //try to load icon for each mod that can have one
if(mod.root.child("icon.png").exists()){ if(mod.root.child("icon.png").exists()){
try{ try{
mod.iconTexture = new Texture(mod.root.child("icon.png")); mod.iconTexture = new Texture(mod.root.child("icon.png"));
mod.iconTexture.setFilter(TextureFilter.linear);
}catch(Throwable t){ }catch(Throwable t){
Log.err("Failed to load icon for mod '" + mod.name + "'.", t); Log.err("Failed to load icon for mod '" + mod.name + "'.", t);
} }
} }
} }
}
private void packSprites(Seq<Fi> sprites, LoadedMod mod, boolean prefix){ private void packSprites(Seq<Fi> sprites, LoadedMod mod, boolean prefix){
for(Fi file : sprites){ for(Fi file : sprites){
@@ -347,6 +368,7 @@ public class Mods implements Loadable{
} }
} }
} }
Events.fire(new FileTreeInitEvent());
//add new keys to each bundle //add new keys to each bundle
I18NBundle bundle = Core.bundle; I18NBundle bundle = Core.bundle;
@@ -587,6 +609,12 @@ public class Mods implements Loadable{
/** Loads a mod file+meta, but does not add it to the list. /** Loads a mod file+meta, but does not add it to the list.
* Note that directories can be loaded as mods. */ * Note that directories can be loaded as mods. */
private LoadedMod loadMod(Fi sourceFile) throws Exception{ private LoadedMod loadMod(Fi sourceFile) throws Exception{
return loadMod(sourceFile, false);
}
/** Loads a mod file+meta, but does not add it to the list.
* Note that directories can be loaded as mods. */
private LoadedMod loadMod(Fi sourceFile, boolean overwrite) throws Exception{
Time.mark(); Time.mark();
ZipFi rootZip = null; ZipFi rootZip = null;
@@ -614,23 +642,47 @@ public class Mods implements Loadable{
String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main; String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main;
String baseName = meta.name.toLowerCase().replace(" ", "-"); String baseName = meta.name.toLowerCase().replace(" ", "-");
if(mods.contains(m -> m.name.equals(baseName))){ var other = mods.find(m -> m.name.equals(baseName));
if(other != null){
//steam mods can't really be deleted, they need to be unsubscribed
if(overwrite && !other.hasSteamID()){
//close zip file
if(other.root instanceof ZipFi){
other.root.delete();
}
//delete the old mod directory
if(other.file.isDirectory()){
other.file.deleteDirectory();
}else{
other.file.delete();
}
//unload
mods.remove(other);
}else{
throw new IllegalArgumentException("A mod with the name '" + baseName + "' is already imported."); throw new IllegalArgumentException("A mod with the name '" + baseName + "' is already imported.");
} }
}
Mod mainMod; Mod mainMod;
Fi mainFile = zip; Fi mainFile = zip;
if(android){
mainFile = mainFile.child("classes.dex");
}else{
String[] path = (mainClass.replace('.', '/') + ".class").split("/"); String[] path = (mainClass.replace('.', '/') + ".class").split("/");
for(String str : path){ for(String str : path){
if(!str.isEmpty()){ if(!str.isEmpty()){
mainFile = mainFile.child(str); mainFile = mainFile.child(str);
} }
} }
}
//make sure the main class exists before loading it; if it doesn't just don't put it there //make sure the main class exists before loading it; if it doesn't just don't put it there
if(mainFile.exists() && Core.settings.getBool("mod-" + baseName + "-enabled", true)){ //if the mod is explicitly marked as java, try loading it anyway
//mobile versions don't support class mods if((mainFile.exists() || meta.java) &&
Core.settings.getBool("mod-" + baseName + "-enabled", true) && Version.isAtLeast(meta.minGameVersion) && (meta.getMinMajor() >= 105 || headless)){
if(ios){ if(ios){
throw new IllegalArgumentException("Java class mods are not supported on iOS."); throw new IllegalArgumentException("Java class mods are not supported on iOS.");
} }
@@ -700,6 +752,20 @@ public class Mods implements Loadable{
this.name = meta.name.toLowerCase().replace(" ", "-"); this.name = meta.name.toLowerCase().replace(" ", "-");
} }
/** @return whether this is a java class mod. */
public boolean isJava(){
return meta.java || main != null;
}
@Nullable
public String getRepo(){
return Core.settings.getString("mod-" + name + "-repo", meta.repo);
}
public void setRepo(String repo){
Core.settings.put("mod-" + name + "-repo", repo);
}
public boolean enabled(){ public boolean enabled(){
return state == ModState.enabled || state == ModState.contentErrors; return state == ModState.enabled || state == ModState.contentErrors;
} }
@@ -720,11 +786,7 @@ public class Mods implements Loadable{
public boolean isSupported(){ public boolean isSupported(){
if(isOutdated()) return false; if(isOutdated()) return false;
int major = getMinMajor(), minor = getMinMinor(); return Version.isAtLeast(meta.minGameVersion);
if(Version.build <= 0) return true;
return Version.build >= major && Version.revision >= minor;
} }
/** @return whether this mod is outdated, e.g. not compatible with v6. */ /** @return whether this mod is outdated, e.g. not compatible with v6. */
@@ -734,33 +796,7 @@ public class Mods implements Loadable{
} }
public int getMinMajor(){ public int getMinMajor(){
int major = 0; return meta.getMinMajor();
String ver = meta.minGameVersion == null ? "0" : meta.minGameVersion;
if(ver.contains(".")){
String[] split = ver.split("\\.");
if(split.length == 2){
major = Strings.parseInt(split[0], 0);
}
}else{
major = Strings.parseInt(ver, 0);
}
return major;
}
public int getMinMinor(){
String ver = meta.minGameVersion == null ? "0" : meta.minGameVersion;
if(ver.contains(".")){
String[] split = ver.split("\\.");
if(split.length == 2){
return Strings.parseInt(split[1], 0);
}
}
return 0;
} }
@Override @Override
@@ -842,6 +878,8 @@ public class Mods implements Loadable{
public Seq<String> dependencies = Seq.with(); public Seq<String> dependencies = Seq.with();
/** Hidden mods are only server-side or client-side, and do not support adding new content. */ /** Hidden mods are only server-side or client-side, and do not support adding new content. */
public boolean hidden; public boolean hidden;
/** If true, this mod should be loaded as a Java class mod. This is technically optional, but highly recommended. */
public boolean java;
public String displayName(){ public String displayName(){
return displayName == null ? name : displayName; return displayName == null ? name : displayName;
@@ -854,6 +892,12 @@ public class Mods implements Loadable{
if(description != null) description = Strings.stripColors(description); if(description != null) description = Strings.stripColors(description);
} }
public int getMinMajor(){
String ver = minGameVersion == null ? "0" : minGameVersion;
int dot = ver.indexOf(".");
return dot != -1 ? Strings.parseInt(ver.substring(0, dot), 0) : Strings.parseInt(ver, 0);
}
@Override @Override
public String toString() { public String toString() {
return "ModMeta{" + return "ModMeta{" +
@@ -863,6 +907,7 @@ public class Mods implements Loadable{
", main='" + main + '\'' + ", main='" + main + '\'' +
", minGameVersion='" + minGameVersion + '\'' + ", minGameVersion='" + minGameVersion + '\'' +
", hidden=" + hidden + ", hidden=" + hidden +
", repo=" + repo +
'}'; '}';
} }
} }

View File

@@ -24,7 +24,7 @@ public class Scripts implements Disposable{
private final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk", private final Seq<String> blacklist = Seq.with(".net.", "java.net", "files", "reflect", "javax", "rhino", "file", "channels", "jdk",
"runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system", "runtime", "util.os", "rmi", "security", "org.", "sun.", "beans", "sql", "http", "exec", "compiler", "process", "system",
".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org."); ".awt", "socket", "classloader", "oracle", "invoke", "java.util.function", "java.util.stream", "org.");
private final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor"); private final Seq<String> whitelist = Seq.with("mindustry.net", "netserver", "netclient", "com.sun.proxy.$proxy", "mindustry.gen.", "mindustry.logic.", "mindustry.async.", "saveio", "systemcursor", "filetreeinitevent");
private final Context context; private final Context context;
private final Scriptable scope; private final Scriptable scope;
private boolean errored; private boolean errored;
@@ -57,7 +57,7 @@ public class Scripts implements Disposable{
public String runConsole(String text){ public String runConsole(String text){
try{ try{
Object o = context.evaluateString(scope, text, "console.js", 1, null); Object o = context.evaluateString(scope, text, "console.js", 1, null);
if(o instanceof NativeJavaObject) o = ((NativeJavaObject)o).unwrap(); if(o instanceof NativeJavaObject n) o = n.unwrap();
if(o instanceof Undefined) o = "undefined"; if(o instanceof Undefined) o = "undefined";
return String.valueOf(o); return String.valueOf(o);
}catch(Throwable t){ }catch(Throwable t){

View File

@@ -273,10 +273,8 @@ public class Net{
*/ */
public void handleServerReceived(NetConnection connection, Object object){ public void handleServerReceived(NetConnection connection, Object object){
if(serverListeners.get(object.getClass()) != null){
if(serverListeners.get(object.getClass()) != null){ if(serverListeners.get(object.getClass()) != null){
serverListeners.get(object.getClass()).get(connection, object); serverListeners.get(object.getClass()).get(connection, object);
}
Pools.free(object); Pools.free(object);
}else{ }else{
Log.err("Unhandled packet type: '@'!", object.getClass()); Log.err("Unhandled packet type: '@'!", object.getClass());

View File

@@ -160,7 +160,7 @@ public class Packets{
public int version; public int version;
public String versionType; public String versionType;
public Seq<String> mods; public Seq<String> mods;
public String name, uuid, usid; public String name, locale, uuid, usid;
public boolean mobile; public boolean mobile;
public int color; public int color;
@@ -169,6 +169,7 @@ public class Packets{
buffer.putInt(Version.build); buffer.putInt(Version.build);
TypeIO.writeString(buffer, versionType); TypeIO.writeString(buffer, versionType);
TypeIO.writeString(buffer, name); TypeIO.writeString(buffer, name);
TypeIO.writeString(buffer, locale);
TypeIO.writeString(buffer, usid); TypeIO.writeString(buffer, usid);
byte[] b = Base64Coder.decode(uuid); byte[] b = Base64Coder.decode(uuid);
@@ -190,6 +191,7 @@ public class Packets{
version = buffer.getInt(); version = buffer.getInt();
versionType = TypeIO.readString(buffer); versionType = TypeIO.readString(buffer);
name = TypeIO.readString(buffer); name = TypeIO.readString(buffer);
locale = TypeIO.readString(buffer);
usid = TypeIO.readString(buffer); usid = TypeIO.readString(buffer);
byte[] idbytes = new byte[16]; byte[] idbytes = new byte[16];
buffer.get(idbytes); buffer.get(idbytes);

View File

@@ -17,6 +17,8 @@ public class Item extends UnlockableContent{
public float flammability = 0f; public float flammability = 0f;
/** how radioactive this item is. 0=none, 1=chernobyl ground zero */ /** how radioactive this item is. 0=none, 1=chernobyl ground zero */
public float radioactivity; public float radioactivity;
/** how electrically potent this item is. */
public float charge = 0f;
/** drill hardness of the item */ /** drill hardness of the item */
public int hardness = 0; public int hardness = 0;
/** /**
@@ -41,6 +43,7 @@ public class Item extends UnlockableContent{
stats.addPercent(Stat.explosiveness, explosiveness); stats.addPercent(Stat.explosiveness, explosiveness);
stats.addPercent(Stat.flammability, flammability); stats.addPercent(Stat.flammability, flammability);
stats.addPercent(Stat.radioactivity, radioactivity); stats.addPercent(Stat.radioactivity, radioactivity);
stats.addPercent(Stat.charge, charge);
} }
@Override @Override

View File

@@ -10,7 +10,7 @@ import mindustry.world.modules.ItemModule.*;
import java.util.*; import java.util.*;
public class ItemSeq implements Iterable<ItemStack>, Serializable{ public class ItemSeq implements Iterable<ItemStack>, JsonSerializable{
protected final int[] values = new int[Vars.content.items().size]; protected final int[] values = new int[Vars.content.items().size];
public int total; public int total;

View File

@@ -25,6 +25,8 @@ public class StatusEffect extends MappableContent{
public float effectChance = 0.15f; public float effectChance = 0.15f;
/** If true, the effect never disappears. */ /** If true, the effect never disappears. */
public boolean permanent; public boolean permanent;
/** If true, this effect will only react with other effects and cannot be applied. */
public boolean reactive;
/** Tint color of effect. */ /** Tint color of effect. */
public Color color = Color.white.cpy(); public Color color = Color.white.cpy();
/** Effect that happens randomly on top of the affected unit. */ /** Effect that happens randomly on top of the affected unit. */
@@ -63,6 +65,7 @@ public class StatusEffect extends MappableContent{
protected void trans(StatusEffect effect, TransitionHandler handler){ protected void trans(StatusEffect effect, TransitionHandler handler){
transitions.put(effect, handler); transitions.put(effect, handler);
effect.transitions.put(this, handler);
} }
protected void opposite(StatusEffect... effect){ protected void opposite(StatusEffect... effect){

View File

@@ -11,6 +11,7 @@ import arc.scene.ui.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.*;
import mindustry.ai.types.*; import mindustry.ai.types.*;
import mindustry.annotations.Annotations.*; import mindustry.annotations.Annotations.*;
import mindustry.content.*; import mindustry.content.*;
@@ -224,6 +225,7 @@ public class UnitType extends UnlockableContent{
Unit inst = constructor.get(); Unit inst = constructor.get();
stats.add(Stat.health, health); stats.add(Stat.health, health);
stats.add(Stat.armor, armor);
stats.add(Stat.speed, speed); stats.add(Stat.speed, speed);
stats.add(Stat.itemCapacity, itemCapacity); stats.add(Stat.itemCapacity, itemCapacity);
stats.add(Stat.range, (int)(maxRange / tilesize), StatUnit.blocks); stats.add(Stat.range, (int)(maxRange / tilesize), StatUnit.blocks);
@@ -292,12 +294,17 @@ public class UnitType extends UnlockableContent{
if(maxRange < 0){ if(maxRange < 0){
maxRange = 0f; maxRange = 0f;
maxRange = Math.max(maxRange, range);
for(Weapon weapon : weapons){ for(Weapon weapon : weapons){
maxRange = Math.max(maxRange, weapon.bullet.range() + hitSize / 2f); maxRange = Math.max(maxRange, weapon.bullet.range() + hitSize / 2f);
} }
} }
if(weapons.isEmpty()){
range = maxRange = miningRange;
}
if(mechStride < 0){ if(mechStride < 0){
mechStride = 4f + (hitSize -8f)/2.1f; mechStride = 4f + (hitSize -8f)/2.1f;
} }

View File

@@ -7,7 +7,7 @@ import arc.scene.ui.layout.*;
import mindustry.graphics.*; import mindustry.graphics.*;
public class BorderImage extends Image{ public class BorderImage extends Image{
public float thickness = 4f; public float thickness = 4f, pad = 0f;
public Color borderColor = Pal.gray; public Color borderColor = Pal.gray;
public BorderImage(){ public BorderImage(){
@@ -40,7 +40,7 @@ public class BorderImage extends Image{
Draw.color(borderColor); Draw.color(borderColor);
Draw.alpha(parentAlpha); Draw.alpha(parentAlpha);
Lines.stroke(Scl.scl(thickness)); Lines.stroke(Scl.scl(thickness));
Lines.rect(x + imageX, y + imageY, imageWidth * scaleX, imageHeight * scaleY); Lines.rect(x + imageX - pad, y + imageY - pad, imageWidth * scaleX + pad*2, imageHeight * scaleY + pad*2);
Draw.reset(); Draw.reset();
} }
} }

View File

@@ -24,9 +24,9 @@ import static mindustry.gen.Tex.*;
@StyleDefaults @StyleDefaults
public class Styles{ public class Styles{
//TODO all these names are inconsistent and not descriptive //TODO all these names are inconsistent and not descriptive
public static Drawable black, black9, black8, black6, black3, black5, none, flatDown, flatOver; public static Drawable black, black9, black8, black6, black3, black5, none, flatDown, flatOver, accentDrawable;
public static ButtonStyle defaultb, waveb, modsb; public static ButtonStyle defaultb, waveb, modsb;
public static TextButtonStyle defaultt, squaret, nodet, cleart, discordt, nonet, infot, clearPartialt, clearTogglet, clearToggleMenut, togglet, transt, fullTogglet, logict; public static TextButtonStyle defaultt, squaret, nodet, cleart, discordt, nonet, infot, clearPartialt, clearTogglet, logicTogglet, clearToggleMenut, togglet, transt, fullTogglet, logict;
public static ImageButtonStyle defaulti, nodei, righti, emptyi, emptytogglei, selecti, logici, geni, colori, accenti, cleari, clearFulli, clearPartiali, clearPartial2i, clearTogglei, clearTransi, clearToggleTransi, clearTogglePartiali; public static ImageButtonStyle defaulti, nodei, righti, emptyi, emptytogglei, selecti, logici, geni, colori, accenti, cleari, clearFulli, clearPartiali, clearPartial2i, clearTogglei, clearTransi, clearToggleTransi, clearTogglePartiali;
public static ScrollPaneStyle defaultPane, horizontalPane, smallPane; public static ScrollPaneStyle defaultPane, horizontalPane, smallPane;
public static KeybindDialogStyle defaultKeybindDialog; public static KeybindDialogStyle defaultKeybindDialog;
@@ -46,6 +46,7 @@ public class Styles{
none = whiteui.tint(0f, 0f, 0f, 0f); none = whiteui.tint(0f, 0f, 0f, 0f);
flatDown = createFlatDown(); flatDown = createFlatDown();
flatOver = whiteui.tint(Color.valueOf("454545")); flatOver = whiteui.tint(Color.valueOf("454545"));
accentDrawable = whiteui.tint(Pal.accent);
defaultb = new ButtonStyle(){{ defaultb = new ButtonStyle(){{
down = buttonDown; down = buttonDown;
@@ -151,6 +152,16 @@ public class Styles{
disabled = black; disabled = black;
disabledFontColor = Color.gray; disabledFontColor = Color.gray;
}}; }};
logicTogglet = new TextButtonStyle(){{
font = Fonts.outline;
fontColor = Color.white;
checked = accentDrawable;
down = accentDrawable;
up = black;
over = flatOver;
disabled = black;
disabledFontColor = Color.gray;
}};
clearToggleMenut = new TextButtonStyle(){{ clearToggleMenut = new TextButtonStyle(){{
font = Fonts.def; font = Fonts.def;
fontColor = Color.white; fontColor = Color.white;

View File

@@ -17,7 +17,7 @@ public class ControlsDialog extends KeybindDialog{
@Override @Override
public void addCloseButton(){ public void addCloseButton(){
buttons.button("@back", Icon.left, this::hide).size(230f, 64f); buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
keyDown(key -> { keyDown(key -> {
if(key == KeyCode.escape || key == KeyCode.back) hide(); if(key == KeyCode.escape || key == KeyCode.back) hide();

View File

@@ -25,8 +25,7 @@ public class CustomGameDialog extends BaseDialog{
void setup(){ void setup(){
clearChildren(); clearChildren();
add(titleTable); add(titleTable).growX().row();
row();
stack(cont, buttons).grow(); stack(cont, buttons).grow();
buttons.bottom(); buttons.bottom();
cont.clear(); cont.clear();

Some files were not shown because too many files have changed in this diff Show More