Compare commits

...

67 Commits
v144 ... v144.2

Author SHA1 Message Date
Anuken
520d122d82 arc 2023-05-21 20:42:34 -04:00
Anuken
7ab9c6fd9c Logic sprite upper limit now 64 2023-05-21 15:47:56 -04:00
Anuken
4d200276d2 Merge remote-tracking branch 'origin/master' 2023-05-21 15:24:30 -04:00
Anuken
c335722de5 Interplanetary accelerator hidden in database 2023-05-21 15:24:23 -04:00
WayZer
25b26be87b fixup! Fix Turret bug when cheat (#8273) (#8629) 2023-05-21 10:59:09 -04:00
Anuken
e714285671 pain 2023-05-21 04:46:50 -04:00
Anuken
dd3ce95264 fixed iOS crash 2023-05-21 04:42:23 -04:00
Anuken
564e81e734 Team#isEnemy is pointless 2023-05-21 03:59:08 -04:00
Anuken
dc63112915 Always hide content when isHidden() == true 2023-05-21 00:57:10 -04:00
Anuken
bc94e24874 Merge remote-tracking branch 'origin/master' 2023-05-20 10:40:39 -04:00
Anuken
94fe92d67d Pathfinder fixes / Hail resprite by Snake#2132 on Discord 2023-05-20 10:40:33 -04:00
MEEPofFaith
047d39d129 Chained PartProgress Operation in Json (#8627)
* Op parsing method

* Parse multi op

* Big brain

* Parse operation array

* Error wording

* Unnecessary code
2023-05-19 21:03:39 -04:00
MEEPofFaith
b6d27c16be Interval bullets for continuous bullets (#8628) 2023-05-19 21:02:54 -04:00
Anuken
7c52444e3c typo 2023-05-19 12:30:45 -04:00
Anuken
1f85d0d24f Load logger in iOS 2023-05-19 12:29:53 -04:00
Anuken
4a53a80b21 Removed redundant team checks 2023-05-19 11:12:32 -04:00
Anuken
cee09dd167 Merge remote-tracking branch 'origin/master' 2023-05-19 11:08:26 -04:00
Anuken
39227774e1 Ripple tint change / Minor optimization 2023-05-19 11:08:18 -04:00
MEEPofFaith
6cd778783e Shift swarmer shoot barrels to match the chutes (#8624)
Similar to how cyclone shoot barrels match the ends of each barrel.
2023-05-19 10:53:06 -04:00
Anuken
5db4c67477 Merge remote-tracking branch 'origin/master' 2023-05-19 00:01:43 -04:00
Anuken
0f87942b16 Fixed #8622 2023-05-19 00:01:36 -04:00
nullevoy
3dd7412ed8 swarmer resprite? (#8573)
* plastic

* swarm

* I did not forget I did not forget I did not forget I did not forget I did not for

* god I can never settle on anything hhhhhhhhhhhhhhhhhhhhhhhhhhhh

* Revert "god I can never settle on anything hhhhhhhhhhhhhhhhhhhhhhhhhhhh"

This reverts commit a59734eb04.

* eh why not

* Revert "eh why not"

This reverts commit c228dc5337.
2023-05-18 19:56:39 -04:00
Anuken
43d164d54b Map list fixes on phones 2023-05-18 12:21:45 -04:00
Anuken
d09695a946 Less MeshBuilder memory usage 2023-05-18 11:54:30 -04:00
Anuken
5976ed6983 Merge remote-tracking branch 'origin/master' 2023-05-18 11:04:04 -04:00
Anuken
d739269f59 Scatter resprite (By Daz from Discord) 2023-05-18 11:03:58 -04:00
Ilya246
72c28f7098 insanius (#8621) 2023-05-18 09:29:44 -04:00
Anuken
f2d83f3599 Vanilla base walls only 2023-05-18 00:45:18 -04:00
Anuken
b611e0f9f4 Tecta buff / Closes Anuken/Mindustry-Suggestions/issues/4427 2023-05-18 00:27:01 -04:00
Anuken
f59c439f2f Some more random schematics 2023-05-17 19:32:47 -04:00
Anuken
e6daf63a5a New base schematcs from Bluewolf 2023-05-17 19:03:16 -04:00
Anuken
00ae28847e New salvo sprite 2023-05-17 18:45:15 -04:00
Anuken
445e147c16 near is further 2023-05-17 09:38:15 -04:00
Anuken
410f4f69a1 near is nearer 2023-05-16 21:15:56 -04:00
Anuken
9e2251028b Merge remote-tracking branch 'origin/master' 2023-05-16 18:13:15 -04:00
Anuken
7f6907e14f More core units for bases 2023-05-16 18:13:09 -04:00
Github Actions
c6829c23d4 Automatic bundle update 2023-05-16 21:26:10 +00:00
Anuken
70293a4864 Merge remote-tracking branch 'origin/master' 2023-05-16 17:24:52 -04:00
Anuken
29855243cb Base building AI is back 2023-05-16 17:24:41 -04:00
Tentyanuk
16358dbd6a Update servers_v7.json (#8615)
Обновили комплектацию серверов
2023-05-16 09:35:12 -04:00
Anuken
83d28461f0 augh 2023-05-16 00:34:12 -04:00
Anuken
874cba7ad3 arc 2023-05-16 00:33:17 -04:00
Anuken
45baeb4933 Log zenity error 2023-05-16 00:16:46 -04:00
Anuken
8b35b44489 Made default CacheLayer add method insert before 'normal' 2023-05-15 22:54:10 -04:00
Anuken
1289e20990 Native (Zenity) file dialogs for Linux 2023-05-15 11:44:08 -04:00
Anuken
3593803ad9 Merge remote-tracking branch 'origin/master' 2023-05-15 10:26:40 -04:00
Anuken
0d89654103 Ignore null messages 2023-05-15 10:26:35 -04:00
GlennFolker
aa7ba6548c Move most planet rendering out of PlanetRenderer to Planet (#8608)
* Planet speaks for itself

* Ok fine keep old Gradle version

* Planet grid mesh builder

* Inline
2023-05-15 09:59:14 -04:00
Vojtak42
9b02d26856 Update bundle_cs.properties (#8610) 2023-05-15 08:54:07 -04:00
BeDanGames
30c773b304 Update servers_v7.json (#8611) 2023-05-15 08:53:54 -04:00
HamzaGSopp
738b96b94b Update servers_v7.json (#8606) 2023-05-14 16:50:20 -04:00
Anuken
151743021b Latest RoboVM 2023-05-13 18:22:01 -04:00
Anuken
dbbb27ec0f Merge remote-tracking branch 'origin/master' 2023-05-13 10:51:10 -04:00
Anuken
89e942ee35 Fixed #8602 2023-05-13 10:51:05 -04:00
BalaM314
5ec0e9dc9f Use shouldExplode, explosionMinWarmup in generators (#8600) 2023-05-13 09:53:47 -04:00
buthed010203
b40615d9e6 Fix crash (#8599) 2023-05-13 09:48:32 -04:00
Anuken
307943c098 Update SERVERLIST.md 2023-05-13 02:41:04 -04:00
Anuken
ebb40145ac Noise filter fix 2023-05-12 15:24:14 -04:00
Anuken
ae272f079b why was this here 2023-05-12 14:26:28 -04:00
Anuken
587c8c280c Better VariableReactorBuild explosion check 2023-05-12 12:16:32 -04:00
Anuken
7bcfaf54ef Fixed #8587 2023-05-12 12:10:37 -04:00
Anuken
bcee2e7083 Neoplasia reactor rebuildable 2023-05-12 02:34:02 -04:00
Anuken
ccf85b81c8 Fixed map list dialog 2023-05-12 02:23:03 -04:00
Anuken
126cca9e86 Gas sprite revert 2023-05-12 02:05:52 -04:00
MEEPofFaith
688b5b9eea Revert "Properly handle missile units shooting more missile units (#8359)" (#8585)
This reverts commit 1373381554.
2023-05-12 01:58:30 -04:00
WayZer
0496d2108c fix NPE in SpawnGroup.write (#8584)
* Update SpawnGroup.java

* Update contributors

* No Objects.isNull
2023-05-11 22:21:05 -04:00
Anuken
06e63dad45 Fixed #8582 2023-05-11 17:05:18 -04:00
142 changed files with 926 additions and 300 deletions

View File

@@ -1,7 +1,7 @@
### Adding a server to the list ### Adding a server to the list
Mindustry now has a public list of servers that everyone can see and connect to. Mindustry now has a public list of servers that everyone can see and connect to.
This is done by letting clients `GET` a [JSON list of servers](https://github.com/Anuken/Mindustry/blob/master/servers_v6.json) in this repository. This is done by letting clients `GET` a [JSON list of servers](https://github.com/Anuken/Mindustry/blob/master/servers_v7.json) in this repository.
You may want to add your server to this list. The steps for getting this done are as follows: You may want to add your server to this list. The steps for getting this done are as follows:
@@ -18,7 +18,7 @@ You'll need to either hire some moderators, or make use of (currently non-existe
4. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option. 4. **Get some good maps.** *(optional, but highly recommended)*. Add some maps to your server and set the map rotation to custom-only. You can get maps from the Steam workshop by subscribing and exporting them; using the `#maps` channel on Discord is also an option.
5. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`). 5. **Check your server configuration.** *(optional)* I would recommend adding a message rate limit of 1 second (`config messageRateLimit 1`), and disabling connect/disconnect messages to reduce spam (`config showConnectMessages false`).
6. Finally, **submit a pull request** to add your server's IP to the list. 6. Finally, **submit a pull request** to add your server's IP to the list.
This should be fairly straightforward: Press the edit button on the [server file](https://github.com/Anuken/Mindustry/blob/master/servers_v6.json), then add a JSON object with a single key, indicating your server address. This should be fairly straightforward: Press the edit button on the [server file](https://github.com/Anuken/Mindustry/blob/master/servers_v7.json), then add a JSON object with a single key, indicating your server address.
For example, if your server address is `example.com:6000`, you would add a comma after the last entry and insert: For example, if your server address is `example.com:6000`, you would add a comma after the last entry and insert:
```json ```json
{ {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 779 B

After

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 B

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 893 B

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

View File

@@ -1 +0,0 @@
mschxœ%ŠQƒ0 C]RÐÄ>v>9Ê"µˆ¶S(HÜ~)X±_dƒƒÏKŒa•YëD­Ý¹(¼¸äS®¢øü²§¯ÆmÃ;VIÓ^es-@

View File

@@ -1,2 +0,0 @@
mschxœ5<C593>Ë
! E¯Ïy-J·ý‡ù(q¤£Gú÷<C3BA>„ââä&'›„Î.<Zl.Çž®Vª{lG¸|<7C>ŸK4ÌíúÙðü{»/ùßR±ÅÒ~•^=ÝùäГkÑïG<C3AF>ç àzRPm!&ÆÌX+ ÉÓ†4©¨²¼H}E“y$9À˜¢XQÜÔü‰æd8ZQŠ¡†acf,Œê˜ã"

View File

@@ -1,2 +0,0 @@
mschxœ5<C593>A E¿JkêÊStã<74><08>˜I
4”šx{¡ðòÿ¼ ¸vÐѽpq<71>°—”Ý^˜Ú}æ­pŠ€ÆÄ…¼§#{Âã¯Ï>Å}SÆmtWØÏKæuÅXGÅq¤ àY¬z\P?E½:<18>ÅYŽ

View File

@@ -1,3 +0,0 @@
mschxœ%Žknà „ÇØIü¨äV9×È
ú;¢xS!a@€“úîMÝ%F¬¾Ñ>fz<>Æ©™p¾~:“¯¥}ŽëõbU$ %MÈÆ;à
ãCeŠ~rT:ûˆ^/6»*ú#yA9²Õ7ϧà#É)%ŒÚ++5¹Ímáꘌ5Ú;™f²ì18Zf•<66>S4Öb0™f™ü5áô¥2w­èƒðÎO„÷ VëÕ$ÙçN+Ÿ1(åíuÞ

View File

@@ -0,0 +1,4 @@
mschxœM<C593>anÂ0 …MK[HÚ"Ä9rŠ<63> <Ô-4(MaÜ~ÏñŸ)RŸíú{vB':Ô´<C394>ý<EFBFBD>iðç¼ú^ñ'å+Ù /ç4Ýóg"jƒÿä°PõþaÉ~¿dwIStxúÌÉñoNpˆ‰ŽK >¹»Ÿ98DW&û¯DÇ<e?OëÍ<C3AB>ãüà<17>Ý•gN^Æu¾pú
ñé®0§S|p´»{Šß\ÆØe…µËñɉš‡_C&;e¾¹%®éÌXú<58>h#gƒxKT!îˆj[ªEªˆ4*­Jé¬iG¨‡-<2D><EFBFBD>ið.<2E>ŽÉvT‰ã@åO¥Ò Ð
Þâ`É
Þ*Þ¢¥<14>Uá:á*”ÁwŠ£<C5A0>jÉ€w,/ÅNø+³~¯6{o”7:Þèx£ã<C2A3>no”7…¯Èê-¬ÚXµéÕ¦×5zµéÕ¦×5z½Å Ü ·õ#誅”-FÅGÅG}„QñƒâÁ÷tDçF-b@tõ½ÔO¼

Binary file not shown.

View File

@@ -0,0 +1 @@
mschxœMŽÍNÃ0„'‰›æ¯^<5E>»Ÿq0‰,9vd»”¼{ ¬»*KÞ<4B>ogV'´„S³†¸XÐO:ŽÁ,Éx ¶êCÛˆòí}@oUÔANÁX—dræ:ËÑ»/½ú€“7VêïÔ˜Hžo*‘ýDc

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
mschŒKà CͯE=
ž§Ê<EFBFBD>B%

View File

@@ -0,0 +1,5 @@
msch
ŚK
Ă0CĺOŇĐEâMŻşpśÁ<C59B>Ně0včő; ń$!„ ł<>Żń <däMJúľ±ěÔ“”s”VĚ»~&<u2U8š`é—d
ŁýHCt„Ţ.I„Wo%ś±u™°pě$a—¬ż“
Î(üÖÂŔhyłN˝ó

Binary file not shown.

View File

@@ -0,0 +1 @@
mschxś5PŃŽ„ @ôáľÄ/şÜ<C59F>Ë,‰ŠAÝËýýµt5!C§Ó™"FŚÝ6Ż î<>ĄĆĆg:bÍű™ËŔ-ó#-ô÷ŹĂ׾ĄkťĎ§gÍËËöNĄbŚeßSť~g˘o/WËu&jć3­ÓQ®yNt`Đ>­ `ů®™TźŞőŚTťôş»j=Ëë>rĹw“A`€Öč%˛IĎQ V*Ĺ˝6ĐË€—Ď<1D>fĄ'Ć0Đ6LZ^Âs0™3ée®™y1 b$=Hz<48>Ř Ę ĘAž2đo°6´†‰ <©ţ/_&

View File

@@ -0,0 +1,2 @@
mschxœ=벓0 å(=¾à³8þà@t¢jöôÉ<C3B4>qjqmÂq(|Ù—µ<C2B5>â|˜ºQ㼘ñjõ¨­æÛ5è¥wæêÍ<8ÙîUÛñç/5òÿ]õkç½v÷Övݢ];8c-š[ÇR«ß¼ëz?;(ãõØ.óêz<C3AA>¬Ÿ§a5jY)mý|Ó/Þøn2ëØ²üKß©º\¥ÒNó <C3B3>]šÞÝç¯v5C;š7ª”5?%¢ôš#ø¾Ný~øË‘ £ïÌÄ~à¡A!á"މ üð6À_•ræ$åªF”2U#>çœyòÃIÄR. `2'ʼD´=¶çö)¿ÏíùجeÛ“ï×Åö›[¤â]Ðâ„D<E2809E>#C&ÓÝ4”HJVx˜ˆÒHj²ÓŽLZr>;XUD"%(BgÁ$QJ”'™X\åÈïµZæS2ÇÎx¯ª` B“zo:M—½©
¾Uð­p$wI%àÌ“G2ïñ¨Þ¹ A#× Èò€"  PHþŸLo´

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
mschxœ%ÐÝrƒ àã˜Üõm:½@³uÌ d“æí»¸^øÁ¸ËYÄÊÕ.„fd—É! ½Ñ6†ùg¿¨œÈmÈ¿\^6R0ôƒ£çâm™è_p9N1­ìñupvæfçÐïë<C3AF>¯ó/3ñ)¸Æ9ÚuÞ3úõIo®ÿôO
\ý$óþNGD=ØÈ¡o\7ïl0»3¼šíi1ßÃH<ëާH¯\(…Fè„E† 5s„\(…Fèîä†YÉdÈÃ

Binary file not shown.

View File

@@ -1212,6 +1212,8 @@ rules.wavetimer = Wave Timer
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Waves rules.waves = Waves
rules.attack = Attack Mode rules.attack = Attack Mode
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI [red](WIP) rules.rtsai = RTS AI [red](WIP)
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1187,6 +1187,8 @@ rules.wavetimer = Інтэрвал хваляў
rules.wavesending = Адпраўка Хваль rules.wavesending = Адпраўка Хваль
rules.waves = Хвалі rules.waves = Хвалі
rules.attack = Рэжым атакі rules.attack = Рэжым атакі
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Мінімальны Размер Атраду rules.rtsminsquadsize = Мінімальны Размер Атраду
rules.rtsmaxsquadsize = Максімальны Размер Атраду rules.rtsmaxsquadsize = Максімальны Размер Атраду

View File

@@ -1198,6 +1198,8 @@ rules.wavetimer = Таймер за Вълни
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Вълни rules.waves = Вълни
rules.attack = Режим Атака rules.attack = Режим Атака
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1202,6 +1202,8 @@ rules.wavetimer = Temporitzador donades
rules.wavesending = Enviament donades rules.wavesending = Enviament donades
rules.waves = Onades rules.waves = Onades
rules.attack = Mode datac rules.attack = Mode datac
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = IA avançada (RTS AI) rules.rtsai = IA avançada (RTS AI)
rules.rtsminsquadsize = Mida mínima de lesquadró rules.rtsminsquadsize = Mida mínima de lesquadró
rules.rtsmaxsquadsize = Mida màxima de lesquadró rules.rtsmaxsquadsize = Mida màxima de lesquadró

View File

@@ -767,7 +767,7 @@ sector.fungalPass.description = Přechodová oblast mezi vysokými horami a spó
sector.biomassFacility.description = Prapůvod všech spór. Toto je zařízení, be kterém byly spóry vynalezeny a zpočátku u vyráběny.\nVynalezni technologii, která se skrýbá uvnitř. Kultivuj spóry k výrobě paliva a plastů.\n\n[lightgray]Po vypnutí tohoto zařízení byly spóry vypuštěny. V okolním ekosystému však tomuto invazivnímu druhu nebylo nic schopné konkurovat. sector.biomassFacility.description = Prapůvod všech spór. Toto je zařízení, be kterém byly spóry vynalezeny a zpočátku u vyráběny.\nVynalezni technologii, která se skrýbá uvnitř. Kultivuj spóry k výrobě paliva a plastů.\n\n[lightgray]Po vypnutí tohoto zařízení byly spóry vypuštěny. V okolním ekosystému však tomuto invazivnímu druhu nebylo nic schopné konkurovat.
sector.windsweptIslands.description = Vzdálen od pevniny je tento řetízek ostrovů. Záznamy ukazují, že zde kdysi byly zařízení na výrobu [accent]Plastany[].\n\nPoraž nepřátelské námořní jednotky. Vybuduj základnu na ostrově. Vynalezni továrny. sector.windsweptIslands.description = Vzdálen od pevniny je tento řetízek ostrovů. Záznamy ukazují, že zde kdysi byly zařízení na výrobu [accent]Plastany[].\n\nPoraž nepřátelské námořní jednotky. Vybuduj základnu na ostrově. Vynalezni továrny.
sector.extractionOutpost.description = Vzdálená pevnost, postavená nepřítelem za účelem vysílání zdrojů do okolních sektorů.\n\nDoprava položek napříč sektory je nezbytná pro lapení dalších sektorů. Znič základnu. Vyzkoumej jejich Vysílací plošiny. sector.extractionOutpost.description = Vzdálená pevnost, postavená nepřítelem za účelem vysílání zdrojů do okolních sektorů.\n\nDoprava položek napříč sektory je nezbytná pro lapení dalších sektorů. Znič základnu. Vyzkoumej jejich Vysílací plošiny.
sector.impact0078.description = Zde leží zbytky mezihvězdné lodi, která vstoupila d otohoto systému.\n\nZachraň z vraku vše, co se dá. Vyzkoumej nepoškozenou technologii. sector.impact0078.description = Zde leží zbytky mezihvězdné lodi, která vstoupila do tohoto systému.\n\nZachraň z vraku vše, co se dá. Vyzkoumej nepoškozenou technologii.
sector.planetaryTerminal.description = Konečný cíl.\n\nTato pobřežní základna obsahuje konstrukce schopné vyslat jádra na okolní planety. Je mimořádně dobře opevněna.\n\nVyrob námořní jednotky. Odstraň nepřítele tak rychle, jak umíš. Vyzkoumej vysílací konstrukci. sector.planetaryTerminal.description = Konečný cíl.\n\nTato pobřežní základna obsahuje konstrukce schopné vyslat jádra na okolní planety. Je mimořádně dobře opevněna.\n\nVyrob námořní jednotky. Odstraň nepřítele tak rychle, jak umíš. Vyzkoumej vysílací konstrukci.
sector.coastline.description = Remnants of naval unit technology have been detected at this location. Repel the enemy attacks, capture this sector, and acquire the technology. sector.coastline.description = Remnants of naval unit technology have been detected at this location. Repel the enemy attacks, capture this sector, and acquire the technology.
sector.navalFortress.description = The enemy has established a base on a remote, naturally-fortified island. Destroy this outpost. Acquire their advanced naval craft technology, and research it. sector.navalFortress.description = The enemy has established a base on a remote, naturally-fortified island. Destroy this outpost. Acquire their advanced naval craft technology, and research it.
@@ -1200,6 +1200,8 @@ rules.wavetimer = Časovač vln
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Vlny rules.waves = Vlny
rules.attack = Režim útoku rules.attack = Režim útoku
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Bølge-æggeur
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Bølger rules.waves = Bølger
rules.attack = Angrebsmode rules.attack = Angrebsmode
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1211,6 +1211,8 @@ rules.wavetimer = Wellen-Timer
rules.wavesending = Manuelle Wellen möglich rules.wavesending = Manuelle Wellen möglich
rules.waves = Wellen rules.waves = Wellen
rules.attack = Angriff-Modus rules.attack = Angriff-Modus
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS KI [red](unfertig) rules.rtsai = RTS KI [red](unfertig)
rules.rtsminsquadsize = Min. Squadgröße rules.rtsminsquadsize = Min. Squadgröße
rules.rtsmaxsquadsize = Max. Squadgröße rules.rtsmaxsquadsize = Max. Squadgröße

View File

@@ -1208,6 +1208,8 @@ rules.wavetimer = Temporizador de oleadas
rules.wavesending = Envío de oleadas rules.wavesending = Envío de oleadas
rules.waves = Oleadas rules.waves = Oleadas
rules.attack = Modo de ataque rules.attack = Modo de ataque
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = IA enemiga avanzada (RTS AI) rules.rtsai = IA enemiga avanzada (RTS AI)
rules.rtsminsquadsize = Tamaño mínimo de escuadrón rules.rtsminsquadsize = Tamaño mínimo de escuadrón
rules.rtsmaxsquadsize = Tamaño máximo de escuadrón rules.rtsmaxsquadsize = Tamaño máximo de escuadrón

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Kasuta taimerit
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Kasuta lahingulaineid rules.waves = Kasuta lahingulaineid
rules.attack = Mänguviis "Rünnak" rules.attack = Mänguviis "Rünnak"
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1190,6 +1190,8 @@ rules.wavetimer = Boladen denboragailua
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Boladak rules.waves = Boladak
rules.attack = Eraso modua rules.attack = Eraso modua
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1187,6 +1187,8 @@ rules.wavetimer = Tasojen aikaraja
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Tasot rules.waves = Tasot
rules.attack = Hyökkäystila rules.attack = Hyökkäystila
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min. hyökkäysjoukon koko rules.rtsminsquadsize = Min. hyökkäysjoukon koko
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1187,6 +1187,8 @@ rules.wavetimer = Wave Timer
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Waves rules.waves = Waves
rules.attack = Attack Mode rules.attack = Attack Mode
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1212,6 +1212,8 @@ rules.wavetimer = Compte à rebours des vagues
rules.wavesending = Déclenchement des Vagues rules.wavesending = Déclenchement des Vagues
rules.waves = Vagues rules.waves = Vagues
rules.attack = Mode « Attaque » rules.attack = Mode « Attaque »
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = IA de RTS [red](WIP) rules.rtsai = IA de RTS [red](WIP)
rules.rtsminsquadsize = Taille Minimale d'une Escouade rules.rtsminsquadsize = Taille Minimale d'une Escouade
rules.rtsmaxsquadsize = Taille Maximale d'une Escouade rules.rtsmaxsquadsize = Taille Maximale d'une Escouade

View File

@@ -1197,6 +1197,8 @@ rules.wavetimer = Hullám időzítő
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Hullámok rules.waves = Hullámok
rules.attack = Támadás mód rules.attack = Támadás mód
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1208,6 +1208,8 @@ rules.wavetimer = Pengaturan Waktu Gelombang
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Gelombang rules.waves = Gelombang
rules.attack = Mode Penyerangan rules.attack = Mode Penyerangan
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = A.I. RTS rules.rtsai = A.I. RTS
rules.rtsminsquadsize = Ukuran Regu Minimum rules.rtsminsquadsize = Ukuran Regu Minimum
rules.rtsmaxsquadsize = Ukuran Regu Maksimum rules.rtsmaxsquadsize = Ukuran Regu Maksimum

View File

@@ -1194,6 +1194,8 @@ rules.wavetimer = Timer Ondate
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Ondate rules.waves = Ondate
rules.attack = Modalità Attacco rules.attack = Modalità Attacco
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Dimensione minima squadra rules.rtsminsquadsize = Dimensione minima squadra
rules.rtsmaxsquadsize = Dimensione massima squadra rules.rtsmaxsquadsize = Dimensione massima squadra

View File

@@ -1200,6 +1200,8 @@ rules.wavetimer = ウェーブの自動進行
rules.wavesending = ウェーブスキップ rules.wavesending = ウェーブスキップ
rules.waves = ウェーブ rules.waves = ウェーブ
rules.attack = アタックモード rules.attack = アタックモード
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = チームの最少人数 rules.rtsminsquadsize = チームの最少人数
rules.rtsmaxsquadsize = チームの最大人数 rules.rtsmaxsquadsize = チームの最大人数

View File

@@ -1200,6 +1200,8 @@ rules.wavetimer = 시간 제한이 있는 단계
rules.wavesending = 단계 넘김 rules.wavesending = 단계 넘김
rules.waves = 단계 rules.waves = 단계
rules.attack = 공격 모드 rules.attack = 공격 모드
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = 최소 부대 규모 rules.rtsminsquadsize = 최소 부대 규모
rules.rtsmaxsquadsize = 최대 부대 규모 rules.rtsmaxsquadsize = 최대 부대 규모

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Bangų Laikmatis
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Bangos rules.waves = Bangos
rules.attack = Puolimo Režimas rules.attack = Puolimo Režimas
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1200,6 +1200,8 @@ rules.wavetimer = Vijandelijke Golven Timer
rules.wavesending = Golven Sturen rules.wavesending = Golven Sturen
rules.waves = Golven rules.waves = Golven
rules.attack = Aanvalmodus rules.attack = Aanvalmodus
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Ploeg Grootte rules.rtsminsquadsize = Min Ploeg Grootte
rules.rtsmaxsquadsize = Max Ploeg Grootte rules.rtsmaxsquadsize = Max Ploeg Grootte

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Wave Timer
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Waves rules.waves = Waves
rules.attack = Attack Mode rules.attack = Attack Mode
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1198,6 +1198,8 @@ rules.wavetimer = Zegar Fal
rules.wavesending = Wysyłanie Fal rules.wavesending = Wysyłanie Fal
rules.waves = Fale rules.waves = Fale
rules.attack = Tryb Ataku rules.attack = Tryb Ataku
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS SI rules.rtsai = RTS SI
rules.rtsminsquadsize = Minimalny Rozmiar Składu rules.rtsminsquadsize = Minimalny Rozmiar Składu
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1209,6 +1209,8 @@ rules.wavetimer = Tempo de horda
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Hordas rules.waves = Hordas
rules.attack = Modo de ataque rules.attack = Modo de ataque
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Tamanho mínimo do esquadrão rules.rtsminsquadsize = Tamanho mínimo do esquadrão
rules.rtsmaxsquadsize = Tamanho máximo do esquadrão rules.rtsmaxsquadsize = Tamanho máximo do esquadrão

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Tempo de horda
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Hordas rules.waves = Hordas
rules.attack = Modo de ataque rules.attack = Modo de ataque
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1200,6 +1200,8 @@ rules.wavetimer = Valuri pe Timp
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Valuri rules.waves = Valuri
rules.attack = Modul Atac rules.attack = Modul Atac
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1200,6 +1200,8 @@ rules.wavetimer = Интервал волн
rules.wavesending = Отправка волн rules.wavesending = Отправка волн
rules.waves = Волны rules.waves = Волны
rules.attack = Режим атаки rules.attack = Режим атаки
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = ИИ в реальном времени rules.rtsai = ИИ в реальном времени
rules.rtsminsquadsize = Минимальный размер отряда rules.rtsminsquadsize = Минимальный размер отряда
rules.rtsmaxsquadsize = Максимальный размер отряда rules.rtsmaxsquadsize = Максимальный размер отряда

View File

@@ -1202,6 +1202,8 @@ rules.wavetimer = Talasna Štoperica
rules.wavesending = Slanje Talasa rules.wavesending = Slanje Talasa
rules.waves = Talasi rules.waves = Talasi
rules.attack = Mod Napada rules.attack = Mod Napada
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI [red](Nedovršeno) rules.rtsai = RTS AI [red](Nedovršeno)
rules.rtsminsquadsize = Minimalna Veličina Odreda rules.rtsminsquadsize = Minimalna Veličina Odreda
rules.rtsmaxsquadsize = Maksimalna Veličina Odreda rules.rtsmaxsquadsize = Maksimalna Veličina Odreda

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Vågtimer
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Vågor rules.waves = Vågor
rules.attack = Attack Mode rules.attack = Attack Mode
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1202,6 +1202,8 @@ rules.wavetimer = นับถอยหลังการปล่อยคล
rules.wavesending = การปล่อยคลื่น rules.wavesending = การปล่อยคลื่น
rules.waves = คลื่น rules.waves = คลื่น
rules.attack = โหมดการโจมตี rules.attack = โหมดการโจมตี
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI [red](ไม่เสถียร) rules.rtsai = RTS AI [red](ไม่เสถียร)
rules.rtsminsquadsize = ขนาดกองทัพเล็กที่สุด rules.rtsminsquadsize = ขนาดกองทัพเล็กที่สุด
rules.rtsmaxsquadsize = ขนาดกองทัพใหญ่ที่สุด rules.rtsmaxsquadsize = ขนาดกองทัพใหญ่ที่สุด

View File

@@ -1188,6 +1188,8 @@ rules.wavetimer = Wave Timer
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = Waves rules.waves = Waves
rules.attack = Attack Mode rules.attack = Attack Mode
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Squad Size rules.rtsminsquadsize = Min Squad Size
rules.rtsmaxsquadsize = Max Squad Size rules.rtsmaxsquadsize = Max Squad Size

View File

@@ -1199,6 +1199,8 @@ rules.wavetimer = Dalga Zamanlayıcısı
rules.wavesending = Dalga Gönderiliyor rules.wavesending = Dalga Gönderiliyor
rules.waves = Dalgalar rules.waves = Dalgalar
rules.attack = Saldırı Modu rules.attack = Saldırı Modu
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Min Gurup Boyutu rules.rtsminsquadsize = Min Gurup Boyutu
rules.rtsmaxsquadsize = Maks Gurup Boyutu rules.rtsmaxsquadsize = Maks Gurup Boyutu

View File

@@ -1210,6 +1210,8 @@ rules.wavetimer = Таймер для хвиль
rules.wavesending = Ручне надсилання хвиль rules.wavesending = Ручне надсилання хвиль
rules.waves = Хвилі rules.waves = Хвилі
rules.attack = Режим атаки rules.attack = Режим атаки
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = ШІ зі стратегій реального часу rules.rtsai = ШІ зі стратегій реального часу
rules.rtsminsquadsize = Мінімальний розмір загону rules.rtsminsquadsize = Мінімальний розмір загону
rules.rtsmaxsquadsize = Максимальний розмір загону rules.rtsmaxsquadsize = Максимальний розмір загону

View File

@@ -1203,6 +1203,8 @@ rules.wavetimer = Đếm ngược đợt
rules.wavesending = Gửi đợt rules.wavesending = Gửi đợt
rules.waves = Đợt rules.waves = Đợt
rules.attack = Chế độ tấn công rules.attack = Chế độ tấn công
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = Kích thước đội hình tối thiểu rules.rtsminsquadsize = Kích thước đội hình tối thiểu
rules.rtsmaxsquadsize = Kích thước đội hình tối đa rules.rtsmaxsquadsize = Kích thước đội hình tối đa

View File

@@ -1211,6 +1211,8 @@ rules.wavetimer = 波次计时器
rules.wavesending = 波次可跳波 rules.wavesending = 波次可跳波
rules.waves = 波次 rules.waves = 波次
rules.attack = 进攻模式 rules.attack = 进攻模式
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = 最小部队规模 rules.rtsminsquadsize = 最小部队规模
rules.rtsmaxsquadsize = 最大部队规模 rules.rtsmaxsquadsize = 最大部队规模

View File

@@ -1207,6 +1207,8 @@ rules.wavetimer = 波次時間
rules.wavesending = Wave Sending rules.wavesending = Wave Sending
rules.waves = 波次 rules.waves = 波次
rules.attack = 攻擊模式 rules.attack = 攻擊模式
rules.buildai = Base Builder AI
rules.buildaitier = Builder AI Tier
rules.rtsai = RTS AI rules.rtsai = RTS AI
rules.rtsminsquadsize = 最小隊伍規模 rules.rtsminsquadsize = 最小隊伍規模
rules.rtsmaxsquadsize = 最大隊伍規模 rules.rtsmaxsquadsize = 最大隊伍規模

View File

@@ -155,3 +155,4 @@ AyuKo-o
JojoFR1 JojoFR1
Xasmedy Xasmedy
xStaBUx xStaBUx
WayZer

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,325 @@
package mindustry.ai;
import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.ai.BaseRegistry.*;
import mindustry.content.*;
import mindustry.core.*;
import mindustry.game.*;
import mindustry.game.Schematic.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
import mindustry.maps.generators.*;
import mindustry.type.*;
import mindustry.world.*;
import mindustry.world.blocks.defense.*;
import mindustry.world.blocks.payloads.*;
import mindustry.world.blocks.production.*;
import mindustry.world.blocks.storage.*;
import mindustry.world.blocks.storage.CoreBlock.*;
import static mindustry.Vars.*;
public class BaseBuilderAI{
private static final Vec2 axis = new Vec2(), rotator = new Vec2();
private static final int attempts = 6, coreUnitMultiplier = 2;
private static final float emptyChance = 0.01f;
private static final int timerStep = 0, timerSpawn = 1, timerRefreshPath = 2;
private static final float placeIntervalMin = 12f, placeIntervalMax = 2f;
private static final int pathStep = 50;
private static final Seq<Tile> tmpTiles = new Seq<>();
private static int correct = 0, incorrect = 0;
private int lastX, lastY, lastW, lastH;
private boolean triedWalls, foundPath;
final TeamData data;
final Interval timer = new Interval(4);
IntSet path = new IntSet();
IntSet calcPath = new IntSet();
@Nullable Tile calcTile;
boolean calculating, startedCalculating;
int calcCount = 0;
int totalCalcs = 0;
Block wallType;
public BaseBuilderAI(TeamData data){
this.data = data;
}
public void update(){
//fill cores.
if(data.team.cores().size > 0){
var core = data.team.cores().first();
for(Item item : content.items()){
core.items.set(item, core.getMaximumAccepted(item));
}
}
if(wallType == null){
wallType = BaseGenerator.getDifficultyWall(1, data.team.rules().buildAiTier / 0.8f);
}
if(data.team.rules().aiCoreSpawn && timer.get(timerSpawn, 60 * 6f) && data.hasCore()){
CoreBlock block = (CoreBlock)data.core().block;
int coreUnits = data.countType(block.unitType);
//create AI core unit(s)
if(!state.isEditor() && coreUnits < data.cores.size * coreUnitMultiplier){
Unit unit = block.unitType.create(data.team);
unit.set(data.cores.random());
unit.add();
Fx.spawn.at(unit);
}
}
//refresh path
if(!calculating && (timer.get(timerRefreshPath, 3f * Time.toMinutes) || !startedCalculating) && data.hasCore()){
calculating = true;
startedCalculating = true;
calcPath.clear();
}
//didn't find tile in time
if(calculating && calcCount >= world.width() * world.height()){
calculating = false;
calcCount = 0;
calcPath.clear();
totalCalcs ++;
}
//calculate path for units so schematics are not placed on it
if(calculating){
if(calcTile == null){
Vars.spawner.eachGroundSpawn((x, y) -> calcTile = world.tile(x, y));
if(calcTile == null){
calculating = false;
}
}else{
var field = pathfinder.getField(data.team, Pathfinder.costGround, Pathfinder.fieldCore);
if(field.weights != null){
int[] weights = field.weights;
for(int i = 0; i < pathStep; i++){
int minCost = Integer.MAX_VALUE;
int cx = calcTile.x, cy = calcTile.y;
boolean foundAny = false;
for(Point2 p : Geometry.d4){
int nx = cx + p.x, ny = cy + p.y, packed = world.packArray(nx, ny);
Tile other = world.tile(nx, ny);
if(other != null && weights[packed] < minCost && weights[packed] != -1){
minCost = weights[packed];
calcTile = other;
foundAny = true;
}
}
//didn't find anything, break out of loop, this will trigger a clear later
if(!foundAny){
calcCount = Integer.MAX_VALUE;
break;
}
calcPath.add(calcTile.pos());
for(Point2 p : Geometry.d8){
calcPath.add(Point2.pack(p.x + calcTile.x, p.y + calcTile.y));
}
//found the end.
if(calcTile.build instanceof CoreBuild b && b.team != data.team){
//clean up calculations and flush results
calculating = false;
calcCount = 0;
path.clear();
path.addAll(calcPath);
calcPath.clear();
calcTile = null;
totalCalcs ++;
foundPath = true;
break;
}
calcCount ++;
}
}
}
}
//only schedule when there's something to build.
if(foundPath && data.plans.isEmpty() && timer.get(timerStep, Mathf.lerp(placeIntervalMin, placeIntervalMax, data.team.rules().buildAiTier))){
//TODO walls are silly, no walls
//if(!triedWalls){
// tryWalls();
// triedWalls = true;
//}
for(int i = 0; i < attempts; i++){
int range = 150;
Position pos = randomPosition();
//when there are no random positions, do nothing.
if(pos == null) return;
Tmp.v1.rnd(Mathf.random(range));
int wx = (int)(World.toTile(pos.getX()) + Tmp.v1.x), wy = (int)(World.toTile(pos.getY()) + Tmp.v1.y);
Tile tile = world.tiles.getc(wx, wy);
//try not to block the spawn point
if(spawner.getSpawns().contains(t -> t.within(tile, tilesize * 40f))){
continue;
}
Seq<BasePart> parts = null;
//pick a completely random base part, and place it a random location
//((yes, very intelligent))
if(tile.drop() != null && Vars.bases.forResource(tile.drop()).any()){
parts = Vars.bases.forResource(tile.drop());
}else if(Mathf.chance(emptyChance)){
parts = Vars.bases.parts;
}
if(parts != null){
BasePart part = parts.random();
if(tryPlace(part, tile.x, tile.y)){
break;
}
}
}
}
}
/** @return a random position from which to seed building. */
private Position randomPosition(){
if(data.hasCore()){
return data.cores.random();
}else if(data.team == state.rules.waveTeam){
return spawner.getSpawns().random();
}
return null;
}
private boolean tryPlace(BasePart part, int x, int y){
int rotation = Mathf.range(2);
axis.set((int)(part.schematic.width / 2f), (int)(part.schematic.height / 2f));
Schematic result = Schematics.rotate(part.schematic, rotation);
int rotdeg = rotation*90;
rotator.set(part.centerX, part.centerY).rotateAround(axis, rotdeg);
//bottom left schematic corner
int cx = x - (int)rotator.x;
int cy = y - (int)rotator.y;
//check valid placeability
for(Stile tile : result.tiles){
int realX = tile.x + cx, realY = tile.y + cy;
if(!Build.validPlace(tile.block, data.team, realX, realY, tile.rotation)){
return false;
}
Tile wtile = world.tile(realX, realY);
if(tile.block instanceof PayloadConveyor || tile.block instanceof PayloadBlock){
//near a building
for(Point2 point : Edges.getEdges(tile.block.size)){
var t = world.build(tile.x + point.x, tile.y + point.y);
if(t != null){
return false;
}
}
}
//may intersect AI path
tmpTiles.clear();
if(tile.block.solid && wtile != null && wtile.getLinkedTilesAs(tile.block, tmpTiles).contains(t -> path.contains(t.pos()))){
return false;
}
}
//make sure at least X% of resource requirements are met
correct = incorrect = 0;
boolean anyDrills = false;
if(part.required instanceof Item){
for(Stile tile : result.tiles){
if(tile.block instanceof Drill){
anyDrills = true;
tile.block.iterateTaken(tile.x + cx, tile.y + cy, (ex, ey) -> {
Tile res = world.rawTile(ex, ey);
if(res.drop() == part.required){
correct ++;
}else if(res.drop() != null){
incorrect ++;
}
});
}
}
}
//fail if not enough fit requirements
if(anyDrills && (incorrect != 0 || correct == 0)){
return false;
}
//queue it
for(Stile tile : result.tiles){
data.plans.add(new BlockPlan(cx + tile.x, cy + tile.y, tile.rotation, tile.block.id, tile.config));
}
lastX = cx - 1;
lastY = cy - 1;
lastW = result.width + 2;
lastH = result.height + 2;
triedWalls = false;
return true;
}
private void tryWalls(){
Block wall = wallType;
Building spawnt = state.rules.defaultTeam.core() != null ? state.rules.defaultTeam.core() : data.team.core();
Tile spawn = spawnt == null ? null : spawnt.tile;
if(spawn == null) return;
for(int wx = lastX; wx <= lastX + lastW; wx++){
outer:
for(int wy = lastY; wy <= lastY + lastH; wy++){
Tile tile = world.tile(wx, wy);
if(tile == null || !tile.block().alwaysReplace) continue;
boolean any = false;
for(Point2 p : Geometry.d8){
if(Angles.angleDist(Angles.angle(p.x, p.y), spawn.angleTo(tile)) > 70){
continue;
}
Tile o = world.tile(tile.x + p.x, tile.y + p.y);
if(o != null && (o.block() instanceof PayloadBlock || o.block() instanceof PayloadConveyor || o.block() instanceof ShockMine)){
continue outer;
}
if(o != null && o.team() == data.team && !(o.block() instanceof Wall)){
any = true;
}
}
tmpTiles.clear();
if(any && Build.validPlace(wall, data.team, tile.x, tile.y, 0) && !tile.getLinkedTilesAs(wall, tmpTiles).contains(t -> path.contains(t.pos()))){
data.plans.add(new BlockPlan(tile.x, tile.y, (short)0, wall.id, null));
}
}
}
}
}

View File

@@ -54,7 +54,10 @@ public class ControlPathfinder{
(PathTile.nearSolid(tile) || PathTile.solid(tile) ? 3 : 0), (PathTile.nearSolid(tile) || PathTile.solid(tile) ? 3 : 0),
costNaval = (team, tile) -> costNaval = (team, tile) ->
(PathTile.solid(tile) || !PathTile.liquid(tile) ? impassable : 1) + //impassable same-team neutral block, or non-liquid
((PathTile.solid(tile) && ((PathTile.team(tile) == team && !PathTile.teamPassable(tile)) || PathTile.team(tile) == 0)) || !PathTile.liquid(tile) ? impassable : 1) +
//impassable synthetic enemy block
((PathTile.team(tile) != team && PathTile.team(tile) != 0) && PathTile.solid(tile) ? wallImpassableCap : 0) +
(PathTile.nearGround(tile) || PathTile.nearSolid(tile) ? 6 : 0); (PathTile.nearGround(tile) || PathTile.nearSolid(tile) ? 6 : 0);
public static boolean showDebug = false; public static boolean showDebug = false;

View File

@@ -58,7 +58,8 @@ public class Pathfinder implements Runnable{
//water //water
(team, tile) -> (team, tile) ->
(PathTile.solid(tile) || !PathTile.liquid(tile) ? 6000 : 1) + (!PathTile.liquid(tile) ? 6000 : 1) +
PathTile.health(tile) * 5 +
(PathTile.nearGround(tile) || PathTile.nearSolid(tile) ? 14 : 0) + (PathTile.nearGround(tile) || PathTile.nearSolid(tile) ? 14 : 0) +
(PathTile.deep(tile) ? 0 : 1) + (PathTile.deep(tile) ? 0 : 1) +
(PathTile.damages(tile) ? 35 : 0) (PathTile.damages(tile) ? 35 : 0)
@@ -527,7 +528,9 @@ public class Pathfinder implements Runnable{
} }
protected boolean passable(int pos){ protected boolean passable(int pos){
return cost.getCost(team.id, pathfinder.tiles[pos]) != impassable; int amount = cost.getCost(team.id, pathfinder.tiles[pos]);
//edge case: naval reports costs of 6000+ for non-liquids, even though they are not technically passable
return amount != impassable && !(cost == costTypes.get(costNaval) && amount >= 6000);
} }
/** Gets targets to pathfind towards. This must run on the main thread. */ /** Gets targets to pathfind towards. This must run on the main thread. */

View File

@@ -12,14 +12,14 @@ import mindustry.world.blocks.ConstructBlock.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class BuilderAI extends AIController{ public class BuilderAI extends AIController{
public static float buildRadius = 1500, retreatDst = 110f, retreatDelay = Time.toSeconds * 2f; public static float buildRadius = 1500, retreatDst = 110f, retreatDelay = Time.toSeconds * 2f, defaultRebuildPeriod = 60f * 2f;
public @Nullable Unit assistFollowing; public @Nullable Unit assistFollowing;
public @Nullable Unit following; public @Nullable Unit following;
public @Nullable Teamc enemy; public @Nullable Teamc enemy;
public @Nullable BlockPlan lastPlan; public @Nullable BlockPlan lastPlan;
public float fleeRange = 370f, rebuildPeriod = 60f * 2f; public float fleeRange = 370f, rebuildPeriod = defaultRebuildPeriod;
public boolean alwaysFlee; public boolean alwaysFlee;
public boolean onlyAssist; public boolean onlyAssist;
@@ -34,6 +34,14 @@ public class BuilderAI extends AIController{
public BuilderAI(){ public BuilderAI(){
} }
@Override
public void init(){
//rebuild much faster with buildAI; there are usually few builder units so this is fine
if(rebuildPeriod == defaultRebuildPeriod && unit.team.rules().buildAi){
rebuildPeriod = 10f;
}
}
@Override @Override
public void updateMovement(){ public void updateMovement(){

View File

@@ -2548,7 +2548,6 @@ public class Blocks{
researchCostMultiplier = 0.4f; researchCostMultiplier = 0.4f;
}}; }};
//TODO stats
fluxReactor = new VariableReactor("flux-reactor"){{ fluxReactor = new VariableReactor("flux-reactor"){{
requirements(Category.power, with(Items.graphite, 300, Items.carbide, 200, Items.oxide, 100, Items.silicon, 600, Items.surgeAlloy, 300)); requirements(Category.power, with(Items.graphite, 300, Items.carbide, 200, Items.oxide, 100, Items.silicon, 600, Items.surgeAlloy, 300));
powerProduction = 120f; powerProduction = 120f;
@@ -2585,7 +2584,6 @@ public class Blocks{
); );
}}; }};
//TODO stats
neoplasiaReactor = new HeaterGenerator("neoplasia-reactor"){{ neoplasiaReactor = new HeaterGenerator("neoplasia-reactor"){{
requirements(Category.power, with(Items.tungsten, 1000, Items.carbide, 300, Items.oxide, 150, Items.silicon, 500, Items.phaseFabric, 300, Items.surgeAlloy, 200)); requirements(Category.power, with(Items.tungsten, 1000, Items.carbide, 300, Items.oxide, 150, Items.silicon, 500, Items.phaseFabric, 300, Items.surgeAlloy, 200));
@@ -2609,7 +2607,6 @@ public class Blocks{
explodeSound = Sounds.largeExplosion; explodeSound = Sounds.largeExplosion;
powerProduction = 140f; powerProduction = 140f;
rebuildable = false;
ambientSound = Sounds.bioLoop; ambientSound = Sounds.bioLoop;
ambientSoundVolume = 0.2f; ambientSoundVolume = 0.2f;
@@ -3126,8 +3123,8 @@ public class Blocks{
drawer = new DrawTurret(){{ drawer = new DrawTurret(){{
parts.add(new RegionPart("-mid"){{ parts.add(new RegionPart("-mid"){{
progress = PartProgress.recoil; progress = PartProgress.recoil;
under = true; under = false;
moveY = -1f; moveY = -1.25f;
}}); }});
}}; }};
@@ -3417,14 +3414,17 @@ public class Blocks{
}} }}
); );
shoot = new ShootAlternate(){{ shoot = new ShootBarrel(){{
barrels = new float[]{
-4, -1.25f, 0,
0, 0, 0,
4, -1.25f, 0
};
shots = 4; shots = 4;
barrels = 3;
spread = 3.5f;
shotDelay = 5f; shotDelay = 5f;
}}; }};
shootY = 7f; shootY = 4.5f;
reload = 30f; reload = 30f;
inaccuracy = 10f; inaccuracy = 10f;
range = 240f; range = 240f;
@@ -3489,11 +3489,16 @@ public class Blocks{
); );
drawer = new DrawTurret(){{ drawer = new DrawTurret(){{
parts.add(new RegionPart("-barrel"){{ parts.add(new RegionPart("-side"){{
progress = PartProgress.recoil.delay(0.5f); //Since recoil is 1-0, cut from the start instead of the end. progress = PartProgress.warmup;
under = true; moveX = 0.6f;
turretHeatLayer = Layer.turret - 0.0001f; moveRot = -15f;
moveY = -1.5f; mirror = true;
layerOffset = 0.001f;
moves.add(new PartMove(PartProgress.recoil, 0.5f, -0.5f, -8f));
}}, new RegionPart("-barrel"){{
progress = PartProgress.recoil;
moveY = -2.5f;
}}); }});
}}; }};
@@ -3502,7 +3507,7 @@ public class Blocks{
reload = 31f; reload = 31f;
consumeAmmoOnce = false; consumeAmmoOnce = false;
ammoEjectBack = 3f; ammoEjectBack = 3f;
recoil = 2f; recoil = 0f;
shake = 1f; shake = 1f;
shoot.shots = 4; shoot.shots = 4;
shoot.shotDelay = 3f; shoot.shotDelay = 3f;
@@ -4658,7 +4663,7 @@ public class Blocks{
recoil = 0.5f; recoil = 0.5f;
fogRadiusMultiuplier = 0.4f; fogRadiusMultiplier = 0.4f;
coolantMultiplier = 6f; coolantMultiplier = 6f;
shootSound = Sounds.missileLaunch; shootSound = Sounds.missileLaunch;
@@ -5814,7 +5819,7 @@ public class Blocks{
}}; }};
interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{ interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 16000, Items.silicon, 11000, Items.thorium, 13000, Items.titanium, 12000, Items.surgeAlloy, 6000, Items.phaseFabric, 5000)); requirements(Category.effect, BuildVisibility.hidden, with(Items.copper, 16000, Items.silicon, 11000, Items.thorium, 13000, Items.titanium, 12000, Items.surgeAlloy, 6000, Items.phaseFabric, 5000));
researchCostMultiplier = 0.1f; researchCostMultiplier = 0.1f;
size = 7; size = 7;
hasPower = true; hasPower = true;

View File

@@ -3258,7 +3258,7 @@ public class UnitTypes{
drag = 0.1f; drag = 0.1f;
speed = 0.6f; speed = 0.6f;
hitSize = 23f; hitSize = 23f;
health = 6700; health = 7300;
armor = 5f; armor = 5f;
lockLegBase = true; lockLegBase = true;
@@ -3271,13 +3271,14 @@ public class UnitTypes{
abilities.add(new ShieldArcAbility(){{ abilities.add(new ShieldArcAbility(){{
region = "tecta-shield"; region = "tecta-shield";
radius = 34f; radius = 36f;
angle = 82f; angle = 82f;
regen = 0.6f; regen = 0.6f;
cooldown = 60f * 8f; cooldown = 60f * 8f;
max = 1500f; max = 2000f;
y = -20f; y = -20f;
width = 6f; width = 6f;
whenShooting = false;
}}); }});
rotateSpeed = 2.1f; rotateSpeed = 2.1f;
@@ -3319,14 +3320,14 @@ public class UnitTypes{
velocityRnd = 0.33f; velocityRnd = 0.33f;
heatColor = Color.red; heatColor = Color.red;
bullet = new MissileBulletType(4.2f, 47){{ bullet = new MissileBulletType(4.2f, 60){{
homingPower = 0.2f; homingPower = 0.2f;
weaveMag = 4; weaveMag = 4;
weaveScale = 4; weaveScale = 4;
lifetime = 55f; lifetime = 55f;
shootEffect = Fx.shootBig2; shootEffect = Fx.shootBig2;
smokeEffect = Fx.shootSmokeTitan; smokeEffect = Fx.shootSmokeTitan;
splashDamage = 60f; splashDamage = 70f;
splashDamageRadius = 30f; splashDamageRadius = 30f;
frontColor = Color.white; frontColor = Color.white;
hitSound = Sounds.none; hitSound = Sounds.none;

View File

@@ -33,7 +33,7 @@ public class ContentLoader{
public ContentLoader(){ public ContentLoader(){
for(ContentType type : ContentType.all){ for(ContentType type : ContentType.all){
contentMap[type.ordinal()] = new Seq<>(); contentMap[type.ordinal()] = new Seq<>(type.contentClass == null ? Object.class : type.contentClass);
contentNameMap[type.ordinal()] = new ObjectMap<>(); contentNameMap[type.ordinal()] = new ObjectMap<>();
} }
} }

View File

@@ -445,6 +445,12 @@ public class Logic implements ApplicationListener{
updateWeather(); updateWeather();
for(TeamData data : state.teams.getActive()){ for(TeamData data : state.teams.getActive()){
//does not work on PvP so built-in attack maps can have it on by default without issues
if(data.team.rules().buildAi && !state.rules.pvp){
if(data.buildAi == null) data.buildAi = new BaseBuilderAI(data);
data.buildAi.update();
}
if(data.team.rules().rtsAi){ if(data.team.rules().rtsAi){
if(data.rtsAi == null) data.rtsAi = new RtsAI(data); if(data.rtsAi == null) data.rtsAi = new RtsAI(data);
data.rtsAi.update(); data.rtsAi.update();

View File

@@ -233,6 +233,8 @@ public class NetClient implements ApplicationListener{
return; return;
} }
if(message == null) return;
if(message.length() > maxTextLength){ if(message.length() > maxTextLength){
throw new ValidateException(player, "Player has sent a message above the text limit."); throw new ValidateException(player, "Player has sent a message above the text limit.");
} }

View File

@@ -14,6 +14,7 @@ import mindustry.type.*;
import mindustry.ui.dialogs.*; import mindustry.ui.dialogs.*;
import rhino.*; import rhino.*;
import java.io.*;
import java.net.*; import java.net.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -140,6 +141,67 @@ public interface Platform{
* @param title The title of the native dialog * @param title The title of the native dialog
*/ */
default void showFileChooser(boolean open, String title, String extension, Cons<Fi> cons){ default void showFileChooser(boolean open, String title, String extension, Cons<Fi> cons){
if(OS.isLinux && !OS.isAndroid){
showZenity(open, title, new String[]{extension}, cons, () -> defaultFileDialog(open, title, extension, cons));
}else{
defaultFileDialog(open, title, extension, cons);
}
}
/** attempt to use the native file picker with zenity, or runs the fallback Runnable if the operation fails */
static void showZenity(boolean open, String title, String[] extensions, Cons<Fi> cons, Runnable fallback){
Threads.daemon(() -> {
try{
String formatted = (title.startsWith("@") ? Core.bundle.get(title.substring(1)) : title).replaceAll("\"", "'");
String last = FileChooser.getLastDirectory().absolutePath();
if(!last.endsWith("/")) last += "/";
//zenity doesn't support filtering by extension
Seq<String> args = Seq.with("zenity",
"--file-selection",
"--title=" + formatted,
"--filename=" + last,
"--confirm-overwrite",
"--file-filter=" + Seq.with(extensions).toString(" ", s -> "*." + s),
"--file-filter=All files | *" //allow anything if the user wants
);
if(!open){
args.add("--save");
}
String result = OS.exec(args.toArray(String.class));
//first line.
if(result.length() > 1 && result.contains("\n")){
result = result.split("\n")[0];
}
//cancelled selection, ignore result
if(result.isEmpty() || result.equals("\n")) return;
if(result.endsWith("\n")) result = result.substring(0, result.length() - 1);
if(result.contains("\n")) throw new IOException("invalid input: \"" + result + "\"");
Fi file = Core.files.absolute(result);
Core.app.post(() -> {
FileChooser.setLastDirectory(file.isDirectory() ? file : file.parent());
if(!open){
cons.get(file.parent().child(file.nameWithoutExtension() + "." + extensions[0]));
}else{
cons.get(file);
}
});
}catch(Exception e){
Log.err(e);
Log.warn("zenity not found, using non-native file dialog. Consider installing `zenity` for native file dialogs.");
Core.app.post(fallback);
}
});
}
static void defaultFileDialog(boolean open, String title, String extension, Cons<Fi> cons){
new FileChooser(title, file -> file.extEquals(extension), open, file -> { new FileChooser(title, file -> file.extEquals(extension), open, file -> {
if(!open){ if(!open){
cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension)); cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension));
@@ -161,11 +223,17 @@ public interface Platform{
default void showMultiFileChooser(Cons<Fi> cons, String... extensions){ default void showMultiFileChooser(Cons<Fi> cons, String... extensions){
if(mobile){ if(mobile){
showFileChooser(true, extensions[0], cons); showFileChooser(true, extensions[0], cons);
}else if(OS.isLinux && !OS.isAndroid){
showZenity(true, "@open", extensions, cons, () -> defaultMultiFileChooser(cons, extensions));
}else{ }else{
new FileChooser("@open", file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show(); defaultMultiFileChooser(cons, extensions);
} }
} }
static void defaultMultiFileChooser(Cons<Fi> cons, String... extensions){
new FileChooser("@open", file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show();
}
/** Hide the app. Android only. */ /** Hide the app. Android only. */
default void hide(){ default void hide(){
} }

View File

@@ -85,6 +85,14 @@ public class UI implements ApplicationListener, Loadable{
Fonts.loadFonts(); Fonts.loadFonts();
} }
public static void loadColors(){
Colors.put("accent", Pal.accent);
Colors.put("unlaunched", Color.valueOf("8982ed"));
Colors.put("highlight", Pal.accent.cpy().lerp(Color.white, 0.3f));
Colors.put("stat", Pal.stat);
Colors.put("negstat", Pal.negativeStat);
}
@Override @Override
public void loadAsync(){ public void loadAsync(){
@@ -92,6 +100,8 @@ public class UI implements ApplicationListener, Loadable{
@Override @Override
public void loadSync(){ public void loadSync(){
loadColors();
Fonts.outline.getData().markupEnabled = true; Fonts.outline.getData().markupEnabled = true;
Fonts.def.getData().markupEnabled = true; Fonts.def.getData().markupEnabled = true;
Fonts.def.setOwnsTexture(false); Fonts.def.setOwnsTexture(false);
@@ -125,12 +135,6 @@ public class UI implements ApplicationListener, Loadable{
ClickListener.clicked = () -> Sounds.press.play(); ClickListener.clicked = () -> Sounds.press.play();
Colors.put("accent", Pal.accent);
Colors.put("unlaunched", Color.valueOf("8982ed"));
Colors.put("highlight", Pal.accent.cpy().lerp(Color.white, 0.3f));
Colors.put("stat", Pal.stat);
Colors.put("negstat", Pal.negativeStat);
drillCursor = Core.graphics.newCursor("drill", Fonts.cursorScale()); drillCursor = Core.graphics.newCursor("drill", Fonts.cursorScale());
unloadCursor = Core.graphics.newCursor("unload", Fonts.cursorScale()); unloadCursor = Core.graphics.newCursor("unload", Fonts.cursorScale());
targetCursor = Core.graphics.newCursor("target", Fonts.cursorScale()); targetCursor = Core.graphics.newCursor("target", Fonts.cursorScale());

View File

@@ -44,6 +44,11 @@ public abstract class Content implements Comparable<Content>{
return minfo.mod == null; return minfo.mod == null;
} }
/** @return whether this content is from a mod. */
public boolean isModded(){
return !isVanilla();
}
@Override @Override
public int compareTo(Content c){ public int compareTo(Content c){
return Integer.compare(id, c.id); return Integer.compare(id, c.id);

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