Compare commits

...

57 Commits
v129 ... v129.2

Author SHA1 Message Date
Anuken
294ab0a81b Better initial bridge arrows 2021-08-04 19:16:14 -04:00
Anuken
aa80f06f7b Cleanup & bullet bugfixes 2021-08-04 19:02:36 -04:00
Anuken
dd738a0108 Removed puddle 'generation' 2021-08-04 18:32:10 -04:00
Anuken
3be5296572 Fixed #5699 2021-08-04 13:52:17 -04:00
Anuken
cfa844f960 Merge branch 'master' of https://github.com/Anuken/Mindustry 2021-08-04 11:35:19 -04:00
Anuken
3b7afec360 arc 2021-08-04 11:35:15 -04:00
GaviTSRA
a9412c4f62 Updated hub ip of TSR Server (#5698) 2021-08-04 09:27:21 -04:00
Arik
2f57705f13 Fix saving tags of overwritten schematic (#5696) 2021-08-04 09:27:01 -04:00
Anuken
ee47bffb1c Merge remote-tracking branch 'origin/master' 2021-08-04 09:26:43 -04:00
Anuken
909c64468f Fixed #5695 / Fixed #5697 2021-08-04 09:26:39 -04:00
RebornTrack970
d7d7b73c54 Mindustry PvP 1v1 test server Added to Omega (#5692)
Fot testing.
2021-08-03 17:16:14 -04:00
Anuken
f820121e08 Sector bugfixes / More sector info 2021-08-03 16:01:27 -04:00
Anuken
0b036acb75 Merge remote-tracking branch 'origin/master' 2021-08-03 10:10:46 -04:00
Anuken
4d4ae7b2db #5690 2021-08-03 10:10:42 -04:00
Darkness6030
7f896723be Small changes in reloadmaps command (#5687)
Idk is it useful, but why not
2021-08-03 09:33:27 -04:00
Anuken
36deb5e225 Fixed #5688 2021-08-03 09:25:41 -04:00
Anuken
116422f1e7 arc 2021-08-02 21:47:29 -04:00
Anuken
a3d1dd91d9 Dispose display framebuffer on remove 2021-08-02 08:53:50 -04:00
Anuken
41964cd130 Unordered damaged building indices 2021-08-01 20:35:10 -04:00
Anuken
d9a92dc10e Minor deployment script fixes 2021-08-01 18:01:36 -04:00
Anuken
9c1f897fff Fixed #5684 2021-08-01 17:00:24 -04:00
Anuken
e64cd905d6 Fixed #5685 2021-08-01 13:27:21 -04:00
Anuken
fc80c23dde Auto-generate block paletted team regions for mods 2021-07-31 21:31:36 -04:00
Anuken
84b69a683a PvP team color palettes 2021-07-31 18:50:55 -04:00
Anuken
79bf77f4be WIP team icons 2021-07-31 18:23:22 -04:00
Anuken
78c35221be arc 2021-07-31 11:22:18 -04:00
Anuken
1d257c1a35 Mod import progress bar 2021-07-31 10:58:09 -04:00
Anuken
ef92236cb4 Gradle 7.1.1 2021-07-31 09:47:44 -04:00
Anuken
90bc18e1bd Fixed #5677 2021-07-31 08:38:03 -04:00
Anuken
9f6c45f4a0 Merge remote-tracking branch 'origin/master' 2021-07-30 22:49:55 -04:00
Anuken
b7842bbb26 warmup = 1 for bridges without power 2021-07-30 22:49:51 -04:00
JrTRinny
589430055e translation update (#5670) 2021-07-30 22:19:27 -04:00
BlueWolf
8f6fe08b1c fix some misleading comments (#5676) 2021-07-30 21:51:35 -04:00
Anuken
f354b6bcca pulverizer drawSpinSprite 2021-07-30 19:43:29 -04:00
Anuken
d02a017c03 arc 2021-07-30 18:59:18 -04:00
Anuken
6d58997f71 arc 2021-07-30 18:35:50 -04:00
Anuken
7d72c4dc63 arc 2021-07-30 18:13:30 -04:00
Anuken
3b9700793c arc 2021-07-30 16:43:26 -04:00
Anuken
0c03c47eb9 Disabled crash sending + arc 2021-07-30 16:26:25 -04:00
Anuken
2d35a024e2 arc 2021-07-30 15:29:12 -04:00
Andrew Antsiferov
eac11045ff Fix typo (#5674)
of the -> of the tile.
2021-07-30 14:57:23 -04:00
Anuken
a7cc6185ad Proper name/impl for "borderless windowed" on Windows 2021-07-30 14:27:46 -04:00
Anuken
d855840fe2 Fixed #5672 2021-07-30 13:05:12 -04:00
Anuken
81419eddbe Merge remote-tracking branch 'origin/master' 2021-07-30 11:58:06 -04:00
Anuken
fc41ad36f7 Fixed damaged building memory leak 2021-07-30 11:58:01 -04:00
RebornTrack970
676a064b6b Updated TR bundle to Build 21565 (#5671) 2021-07-30 10:46:25 -04:00
Anuken
9e1ba3e235 Darkened chat background slightly 2021-07-30 09:33:35 -04:00
Anuken
ad23544f24 Merge remote-tracking branch 'origin/master' 2021-07-29 11:26:07 -04:00
Anuken
296f9b9da5 Smoother bridge animation start/stop 2021-07-29 11:26:01 -04:00
buthed010203
47398f71a8 Utility method for mods (#5667)
* Utility method for mods

I don't want to have to read something this horrible ever again ![](https://aethex.is-a.fail/55DesOkHk.png)

* Update StorageBlock.java
2021-07-29 11:13:10 -04:00
Anuken
a36f872b61 Use ModLoadException instead of IllegalArgumentException 2021-07-29 09:20:51 -04:00
Anuken
dbebe2ab29 Merge remote-tracking branch 'origin/master' 2021-07-29 09:16:58 -04:00
Anuken
ccb973d1dd Log incompatible mod class loaders 2021-07-29 09:16:53 -04:00
buthed010203
132b1fe0c4 This bothers me (#5664)
* This bothers me

absolutely horrible

* Update gradle.properties
2021-07-28 18:23:23 -04:00
Anuken
8702ebd706 Update deployment.yml 2021-07-28 18:20:08 -04:00
Anuken
4734261097 Fixed unit building not starting when some resources are missing 2021-07-28 18:08:17 -04:00
Anuken
78f55765c1 Clear fallback sprite for core thrusters 2021-07-28 17:49:01 -04:00
65 changed files with 398 additions and 170 deletions

View File

@@ -39,7 +39,7 @@ jobs:
cp -a Mindustry/core/build/javadoc/. docs/ cp -a Mindustry/core/build/javadoc/. docs/
cd docs cd docs
git add . git add .
git commit -m "Update ${RELEASE_VERSION:1}" git commit --allow-empty -m "Update ${RELEASE_VERSION:1}"
git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/MindustryGame/docs git push https://Anuken:${{ secrets.API_TOKEN_GITHUB }}@github.com/MindustryGame/docs
cd ../Mindustry cd ../Mindustry
- name: Update F-Droid build string - name: Update F-Droid build string

View File

@@ -0,0 +1 @@
{version:1,fields:[{name:amount,type:float},{name:liquid,type:mindustry.type.Liquid},{name:tile,type:mindustry.world.Tile},{name:x,type:float},{name:y,type:float}]}

View File

@@ -341,7 +341,11 @@ project(":core"){
} }
} }
def changelogs = file("../fastlane/metadata/android/en-US/changelogs/") def changelogs = file("../fastlane/metadata/android/en-US/changelogs/")
new File(changelogs, androidVersion + ".txt").text = (result) changelogs.mkdirs()
try{
new File(changelogs, androidVersion + ".txt").text = (result)
}catch(Exception ignored){
}
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

View File

@@ -317,7 +317,7 @@ data.invalid = This isn't valid game data.
data.import.confirm = Importing external data will overwrite[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately. data.import.confirm = Importing external data will overwrite[scarlet] all[] your current game data.\n[accent]This cannot be undone![]\n\nOnce the data is imported, your game will exit immediately.
quit.confirm = Are you sure you want to quit? quit.confirm = Are you sure you want to quit?
loading = [accent]Loading... loading = [accent]Loading...
reloading = [accent]Reloading Mods... downloading = [accent]Downloading...
saving = [accent]Saving... saving = [accent]Saving...
respawn = [accent][[{0}][] to respawn in core respawn = [accent][[{0}][] to respawn in core
cancelbuilding = [accent][[{0}][] to clear plan cancelbuilding = [accent][[{0}][] to clear plan
@@ -876,6 +876,7 @@ setting.seconds = {0} seconds
setting.milliseconds = {0} milliseconds setting.milliseconds = {0} milliseconds
setting.fullscreen.name = Fullscreen setting.fullscreen.name = Fullscreen
setting.borderlesswindow.name = Borderless Window setting.borderlesswindow.name = Borderless Window
setting.borderlesswindow.name.windows = Borderless Fullscreen
setting.borderlesswindow.description = Restart may be required to apply changes. setting.borderlesswindow.description = Restart may be required to apply changes.
setting.fps.name = Show FPS & Ping setting.fps.name = Show FPS & Ping
setting.smoothcamera.name = Smooth Camera setting.smoothcamera.name = Smooth Camera
@@ -1102,7 +1103,6 @@ unit.reign.name = Reign
unit.vela.name = Vela unit.vela.name = Vela
unit.corvus.name = Corvus unit.corvus.name = Corvus
block.resupply-point.name = Resupply Point
block.parallax.name = Parallax block.parallax.name = Parallax
block.cliff.name = Cliff block.cliff.name = Cliff
block.sand-boulder.name = Sand Boulder block.sand-boulder.name = Sand Boulder
@@ -1405,8 +1405,7 @@ liquid.slag.description = Refined in separators into constituent metals, or spra
liquid.oil.description = Used in advanced material production and as incendiary ammunition. liquid.oil.description = Used in advanced material production and as incendiary ammunition.
liquid.cryofluid.description = Used as coolant in reactors, turrets and factories. liquid.cryofluid.description = Used as coolant in reactors, turrets and factories.
block.derelict = [lightgray]Derelict block.derelict = [lightgray]Derelict
block.resupply-point.description = Resupplies nearby units with copper ammunition. Not compatible with units that require battery power.
block.armored-conveyor.description = Moves items forward. Does not accept inputs from the sides. block.armored-conveyor.description = Moves items forward. Does not accept inputs from the sides.
block.illuminator.description = Emits light. block.illuminator.description = Emits light.
block.message.description = Stores a message for communication between allies. block.message.description = Stores a message for communication between allies.

View File

@@ -605,7 +605,7 @@ planet.sun.name = ดวงอาทิตย์
sector.impact0078.name = อิมแพค 0078 sector.impact0078.name = อิมแพค 0078
sector.groundZero.name = กราวน์ ซีโร่ sector.groundZero.name = กราวน์ ซีโร่
sector.craters.name = บ่ออุกกาบาต sector.craters.name = บ่ออุกกาบาต
sector.frozenForest.name = ป่าหนาวหน็บ sector.frozenForest.name = ป่าหนาวหน็บ
sector.ruinousShores.name = ชายฝั่งพังทลาย sector.ruinousShores.name = ชายฝั่งพังทลาย
sector.stainedMountains.name = ภูเขาหลากสี sector.stainedMountains.name = ภูเขาหลากสี
sector.desolateRift.name = เดโซเลต ริฟต์ sector.desolateRift.name = เดโซเลต ริฟต์
@@ -624,8 +624,8 @@ sector.frozenForest.description = แม้แต่ที่นี่ ที่
sector.saltFlats.description = ณ ขอบของทะเลทราย เป็นที่ตั้งของที่ราบเกลือ สามารถพบทรัพยากรบางอย่างได้ที่นี่\n\nศัตรูได้ตั้งฐานเก็บทรัพยากรไว้ที่นี่ ทำลายแกนกลางของพวกมัน อย่าให้มีอะไรเหลือ sector.saltFlats.description = ณ ขอบของทะเลทราย เป็นที่ตั้งของที่ราบเกลือ สามารถพบทรัพยากรบางอย่างได้ที่นี่\n\nศัตรูได้ตั้งฐานเก็บทรัพยากรไว้ที่นี่ ทำลายแกนกลางของพวกมัน อย่าให้มีอะไรเหลือ
sector.craters.description = น้ำขังอยู่ในหลุมอุกกาบาศแห่งนี้ อนุสรณ์สถานของสงครามเก่าแก่ ยึดพื้นที่นี่มา เก็บทราย เผา[accent]กระจกเมต้า[] ปั๊มน้ำเพื่อมาหล่อเย็นป้อมปืนและเครื่องขุดเจาะ sector.craters.description = น้ำขังอยู่ในหลุมอุกกาบาศแห่งนี้ อนุสรณ์สถานของสงครามเก่าแก่ ยึดพื้นที่นี่มา เก็บทราย เผา[accent]กระจกเมต้า[] ปั๊มน้ำเพื่อมาหล่อเย็นป้อมปืนและเครื่องขุดเจาะ
sector.ruinousShores.description = ถัดจากทะเลทราย เป็นที่ตั้งของชายฝั่ง ที่ครั้งก่อน เคยเป็นที่ตั้งของฐานป้องกันชายฝั่ง ซึ่งทุกทำลายไปซะส่วนใหญ่แล้ว มีเหลือแค่ระบบการป้องกันพื้นฐาน ทุกอย่างที่เหลือถูกทำลายเหลือเพียงแค่เศษเหล็ก\n\nทำการขยายการสำรวจต่อไป ค้นพบกับเทคโนโลยีอีกครั้ง sector.ruinousShores.description = ถัดจากทะเลทราย เป็นที่ตั้งของชายฝั่ง ที่ครั้งก่อน เคยเป็นที่ตั้งของฐานป้องกันชายฝั่ง ซึ่งทุกทำลายไปซะส่วนใหญ่แล้ว มีเหลือแค่ระบบการป้องกันพื้นฐาน ทุกอย่างที่เหลือถูกทำลายเหลือเพียงแค่เศษเหล็ก\n\nทำการขยายการสำรวจต่อไป ค้นพบกับเทคโนโลยีอีกครั้ง
sector.stainedMountains.description = เข้าลึกไปในพื้นที่ จะพบกับภูเขา ซึ่งยังไม่ถูกสปอร์แตะต้อง\nขุด[accent]ไทเทเนี่ยม[]ที่อุดมสมบูรณ์ในพื้นที่นี้ เรียนรู้ที่จะใช้มัน\n\nมีศัตรูมากขึ้นในบริเวณนี้ อย่าปล่อยให้พวกมันส่งยูนิตที่แข็งแกร่งที่สุดของพวกมันออกมา sector.stainedMountains.description = เข้าลึกไปในพื้นที่ จะพบกับภูเขา ซึ่งยังไม่ถูกสปอร์แตะต้อง\nขุด[accent]ไทเทเนี่ยม[]ที่อุดมสมบูรณ์ในพื้นที่นี้ เรียนรู้ที่จะใช้มัน\n\nมีศัตรูปรากฏตัวมากขึ้นในบริเวณนี้ อย่าปล่อยให้พวกมันส่งยูนิตที่แข็งแกร่งที่สุดออกมา
sector.overgrowth.description = พื้นที่นี้ถูกปกคลุมไปด้วยพืช เข้าใกล้กับแหล่งกำเนิดของสปอร์\nศัตรูได้ตั้งฐานเฝ้าระวังไว้ที่นี่ สร้างยูนิตเมส ทำลายฐานซะ\nวิจัย[accent]เครื่องพัฒนารุ่นยกกำลัง[]เพื่อผลิตยูนิตขนาดที่ใหญ่ขึ้น sector.overgrowth.description = พื้นที่นี้ถูกปกคลุมไปด้วยพืช เข้าใกล้กับแหล่งกำเนิดของสปอร์\nศัตรูได้ตั้งฐานเฝ้าระวังไว้ที่นี่ สร้างยูนิตเมส ทำลายฐานทิ้งซะ\nวิจัย[accent]เครื่องพัฒนารุ่นยกกำลัง[]เพื่อผลิตยูนิตขนาดที่ใหญ่ขึ้น
sector.tarFields.description = ขอบของพื้นที่ผลิตน้ำมัน อยู่ระหว่างภูเขาและทะเลทราย หนึ่งในพื้นที่ที่มีแหล่งน้ำมันดิบที่ใช้งานได้\nแม้ว่าจะถูกทิ้งร้าง พื้นที่นี้ยังคงมีฐานทัพของศัตรูอยู่ใกล้ๆ อย่าประมาทกับพวกมัน\n\n[lightgray]วิจัยเทคโนโลยีการแปรรูปน้ำมันหากเป็นไปได้ sector.tarFields.description = ขอบของพื้นที่ผลิตน้ำมัน อยู่ระหว่างภูเขาและทะเลทราย หนึ่งในพื้นที่ที่มีแหล่งน้ำมันดิบที่ใช้งานได้\nแม้ว่าจะถูกทิ้งร้าง พื้นที่นี้ยังคงมีฐานทัพของศัตรูอยู่ใกล้ๆ อย่าประมาทกับพวกมัน\n\n[lightgray]วิจัยเทคโนโลยีการแปรรูปน้ำมันหากเป็นไปได้
sector.desolateRift.description = เป็นพื้นที่ที่อันตรายมาก ทรัพยากรมากมาย แต่พื้นที่แคบ ความเสี่ยงการโดนทำลายล้างสูง ออกไปจากที่นี่ให้เร็วที่สุด อย่าถูกหลอกโดยระยะเวลาระหว่างการโจมตีของศัตรูที่เว้นไว้นานกว่าปกติ sector.desolateRift.description = เป็นพื้นที่ที่อันตรายมาก ทรัพยากรมากมาย แต่พื้นที่แคบ ความเสี่ยงการโดนทำลายล้างสูง ออกไปจากที่นี่ให้เร็วที่สุด อย่าถูกหลอกโดยระยะเวลาระหว่างการโจมตีของศัตรูที่เว้นไว้นานกว่าปกติ
sector.nuclearComplex.description = สถานที่ผลิตและแปรรูปทอเรี่ยมเก่า ถูกทำลายไม่เหลือสิ้น\nวิจัยทอเรี่ยมและวิธีการใช้มัน\n\nศัตรูในบริเวณนี้มีจำนวนมาก คอยตรวจตราหาผู้บุกรุกอยู่ตลอดเวลา sector.nuclearComplex.description = สถานที่ผลิตและแปรรูปทอเรี่ยมเก่า ถูกทำลายไม่เหลือสิ้น\nวิจัยทอเรี่ยมและวิธีการใช้มัน\n\nศัตรูในบริเวณนี้มีจำนวนมาก คอยตรวจตราหาผู้บุกรุกอยู่ตลอดเวลา
@@ -835,6 +835,7 @@ category.items = ไอเท็ม
category.crafting = การผลิต category.crafting = การผลิต
category.function = ฟังค์ชั่น category.function = ฟังค์ชั่น
category.optional = ทางเลือกการเพิ่มประสิทธิภาพ category.optional = ทางเลือกการเพิ่มประสิทธิภาพ
setting.skipcoreanimation.name = ข้ามแอนิเมชั่นบิน/ลงจอดของแกนกลาง
setting.landscape.name = ล็อกภูมิทัศน์แนวนอน setting.landscape.name = ล็อกภูมิทัศน์แนวนอน
setting.shadows.name = เงา setting.shadows.name = เงา
setting.blockreplace.name = แนะนำบล็อกโดยอัตโนมัติ setting.blockreplace.name = แนะนำบล็อกโดยอัตโนมัติ
@@ -1372,8 +1373,8 @@ hint.payloadDrop.mobile = [accent]กดค้างไว้[]ที่พื
hint.waveFire = ป้อมปืน[accent]คลื่นน้ำ[]หากเติมน้ำเข้าไปจะช่วยดับไฟรอบข้างให้อัตโนมัติ hint.waveFire = ป้อมปืน[accent]คลื่นน้ำ[]หากเติมน้ำเข้าไปจะช่วยดับไฟรอบข้างให้อัตโนมัติ
hint.generator = \uf879 [accent]เครื่องกำเนิดไฟฟ้าเผาไหม้[]จะเผาถ่านและส่งพลังงานไปยังบล็อกที่อยู่ใกล้ๆ\n\nระยะของพลังงานสามารถขยายได้ด้วย \uf87f [accent]ตัวจ่ายพลังงาน[] hint.generator = \uf879 [accent]เครื่องกำเนิดไฟฟ้าเผาไหม้[]จะเผาถ่านและส่งพลังงานไปยังบล็อกที่อยู่ใกล้ๆ\n\nระยะของพลังงานสามารถขยายได้ด้วย \uf87f [accent]ตัวจ่ายพลังงาน[]
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การวิจัยใหม่ที่โฮสต์ได้วิจัยก็เก็บเป็นของคุณด้วย
@@ -1536,7 +1537,7 @@ block.arc.description = ยิงสายฟ้าใส่ศัตรูพ
block.swarmer.description = ยิงขีปนาวุธติดตามตัวใส่ศัตรูทั้งอากาศและพื้นดิน block.swarmer.description = ยิงขีปนาวุธติดตามตัวใส่ศัตรูทั้งอากาศและพื้นดิน
block.salvo.description = ป้อมปืนขนาดกลาง ระดมยิงกระสุนหนักใส่ศัตรูอย่างรวดเร็ว block.salvo.description = ป้อมปืนขนาดกลาง ระดมยิงกระสุนหนักใส่ศัตรูอย่างรวดเร็ว
block.fuse.description = ป้อมปืนระยะใกล้ขนาดใหญ่ ยิงลำแสงเจาะทะลุสามแฉกใส่ศัตรูที่อยู่ใกล้เคียง block.fuse.description = ป้อมปืนระยะใกล้ขนาดใหญ่ ยิงลำแสงเจาะทะลุสามแฉกใส่ศัตรูที่อยู่ใกล้เคียง
block.ripple.description = ป้อมปืนใหญ่ทรงพลัง ยิงลูกระเบิดเป็นกระจุกใส่ศัตรูพื้นดินจากระยะไกล block.ripple.description = ป้อมปืนใหญ่อันทรงพลัง ยิงลูกระเบิดเป็นกระจุกใส่ศัตรูพื้นดินจากระยะไกล
block.cyclone.description = ป้อมปืนรวดเร็วดั่งพายุ ยิงก้อนสะเก็ดระเบิดใส่ยูนิตศัตรูอย่างรวดเร็ว block.cyclone.description = ป้อมปืนรวดเร็วดั่งพายุ ยิงก้อนสะเก็ดระเบิดใส่ยูนิตศัตรูอย่างรวดเร็ว
block.spectre.description = ปืนใหญ่คู่ขนาดยักษ์ ยิงกระสุนเจาะเกราะใส่ศัตรูทั้งบนอากาศและพื้นดิน block.spectre.description = ปืนใหญ่คู่ขนาดยักษ์ ยิงกระสุนเจาะเกราะใส่ศัตรูทั้งบนอากาศและพื้นดิน
block.meltdown.description = ชาร์จแล้วยิงลำแสงเลเซอร์ใส่ศัตรูที่อยู่ใกล้เคียงอย่างต่อเนื่อง ต้องมีของเหลวมาหล่อเย็นป้อมปืนเพื่อทำงาน block.meltdown.description = ชาร์จแล้วยิงลำแสงเลเซอร์ใส่ศัตรูที่อยู่ใกล้เคียงอย่างต่อเนื่อง ต้องมีของเหลวมาหล่อเย็นป้อมปืนเพื่อทำงาน
@@ -1551,13 +1552,13 @@ block.overdrive-dome.description = เร่งประสิทธิภา
block.payload-conveyor.description = เคลื่อนย้ายสิ่งของบรรทุกหนัก อย่างเช่นยูนิต block.payload-conveyor.description = เคลื่อนย้ายสิ่งของบรรทุกหนัก อย่างเช่นยูนิต
block.payload-router.description = แยกสิ่งของบรรทุกออกเป็นสามทิศทาง block.payload-router.description = แยกสิ่งของบรรทุกออกเป็นสามทิศทาง
block.command-center.description = ควบคุมและสั่งการยูนิตด้วยคำสั่งที่มีมากมาย block.command-center.description = ควบคุมและสั่งการยูนิตด้วยคำสั่งที่มีมากมาย
block.ground-factory.description = ผลิตยูนิตทางบก ยูนิตที่ผลิตสามารถใช้ได้เลย หรือนำไปใส่ในเครื่องพัฒนาเพื่ออัเกรด block.ground-factory.description = ผลิตยูนิตทางบก ยูนิตที่ผลิตสามารถใช้ได้เลย หรือนำไปใส่ในเครื่องพัฒนาเพื่ออัเกรด
block.air-factory.description = ผลิตยูนิตทางอากาศ ยูนิตที่ผลิตสามารถใช้ได้เลย หรือนำไปใส่ในเครื่องพัฒนาเพื่ออัเกรด block.air-factory.description = ผลิตยูนิตทางอากาศ ยูนิตที่ผลิตสามารถใช้ได้เลย หรือนำไปใส่ในเครื่องพัฒนาเพื่ออัเกรด
block.naval-factory.description = ผลิตยูนิตเรือ ยูนิตที่ผลิตสามารถใช้ได้เลย หรือนำไปใส่ในเครื่องพัฒนาเพื่ออัเกรด block.naval-factory.description = ผลิตยูนิตเรือ ยูนิตที่ผลิตสามารถใช้ได้เลย หรือนำไปใส่ในเครื่องพัฒนาเพื่ออัเกรด
block.additive-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่สอง block.additive-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่สอง
block.multiplicative-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่สาม block.multiplicative-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่สาม
block.exponential-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่สี่ block.exponential-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่สี่
block.tetrative-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่ห้าและรุ่นสุดท้าย block.tetrative-reconstructor.description = อัเกรดยูนิตที่อยู่ข้างในให้เป็นรุ่นที่ห้าและรุ่นสุดท้าย
block.switch.description = สวิตช์เปิดปิดได้ สามารถควบคุมหรืออ่านค่าได้ด้วยตัวประมวลผลลอจิก block.switch.description = สวิตช์เปิดปิดได้ สามารถควบคุมหรืออ่านค่าได้ด้วยตัวประมวลผลลอจิก
block.micro-processor.description = รันคำสั่งลอจิกเป็นลำดับวนไปวนมา สามารถใช้ควบคุมยูนิตหรือสิ่งก่อสร้าง ไม่ค่อยเร็วเท่าไหร่ block.micro-processor.description = รันคำสั่งลอจิกเป็นลำดับวนไปวนมา สามารถใช้ควบคุมยูนิตหรือสิ่งก่อสร้าง ไม่ค่อยเร็วเท่าไหร่
block.logic-processor.description = รันคำสั่งลอจิกเป็นลำดับวนไปวนมา สามารถใช้ควบคุมยูนิตหรือสิ่งก่อสร้าง ค่อนข้างเร็ว มีระยะการเชื่อมต่อที่ค่อนข้างไกล block.logic-processor.description = รันคำสั่งลอจิกเป็นลำดับวนไปวนมา สามารถใช้ควบคุมยูนิตหรือสิ่งก่อสร้าง ค่อนข้างเร็ว มีระยะการเชื่อมต่อที่ค่อนข้างไกล
@@ -1603,9 +1604,9 @@ unit.omura.description = ยิงลำแสงปืนเรลกันเ
unit.alpha.description = ปกป้องแกนกลางชาร์ดจากศัตรู สร้างสิ่งต่างๆ unit.alpha.description = ปกป้องแกนกลางชาร์ดจากศัตรู สร้างสิ่งต่างๆ
unit.beta.description = ปกป้องแกนกลางฟาวน์เดชั่นจากศัตรู สร้างสิ่งต่างๆ unit.beta.description = ปกป้องแกนกลางฟาวน์เดชั่นจากศัตรู สร้างสิ่งต่างๆ
unit.gamma.description = ปกป้องแกนกลางนิวเคลียสจากศัตรู สร้างสิ่งต่างๆ unit.gamma.description = ปกป้องแกนกลางนิวเคลียสจากศัตรู สร้างสิ่งต่างๆ
unit.retusa.description = วางทุ่นระเบิดระยะใกล้ ซ่อมแซมยูนิตพวกพ้องที่อยู่ใกล้เคียง unit.retusa.description = วางทุ่นระเบิดระยะใกล้ และซ่อมแซมยูนิตพวกพ้องที่อยู่ใกล้เคียง
unit.oxynoe.description = ยิงเปลวไฟเผาไหม้ใส่ศัตรูที่อยู่ใกล้เคียงและซ่อมแซมสิ่งก่อสร้างของพวกพ้อง\nทำลายกระสุนที่กำลังเข้ามาด้วยปืนป้องกันจุด unit.oxynoe.description = ยิงเปลวไฟเผาไหม้ใส่ศัตรูที่อยู่ใกล้เคียงและซ่อมแซมสิ่งก่อสร้างของพวกพ้อง\nทำลายกระสุนที่กำลังเข้ามาด้วยปืนป้องกันจุด
unit.cyerce.description = ยิงขีปนาวุธพลาสม่าติดตามตัวเป็นกระจุกระเบิดใส่ศัตรู\nซ่อมแซมยูนิตพวกพ้องที่อยู่ใกล้เคียง unit.cyerce.description = ยิงขีปนาวุธพลาสม่าติดตามตัวเป็นกระจุกระเบิดใส่ศัตรู\nซ่อมแซมยูนิตพวกพ้องที่อยู่ใกล้เคียงด้วยปืนซ่อมแซม
unit.aegires.description = ช็อตทุกสิ่งก่อสร้างและยูนิตศัตรูที่เข้ามาในสนามพลังงานของมัน\nซ่อมแซมสิ่งก่อสร้างและยูนิตพวกพ้อง unit.aegires.description = ช็อตทุกสิ่งก่อสร้างและยูนิตศัตรูที่เข้ามาในสนามพลังงานของมัน\nซ่อมแซมสิ่งก่อสร้างและยูนิตพวกพ้อง
unit.navanax.description = ยิงลูกระเบิดคลื่นชีพจรแม่เหล็กขนาดใหญ่ สร้างความเสียหายอย่างหนักให้กับเครือข่ายพลังงานศัตรู\nและซ่อมแซมสิ่งก่อสร้างของพวกพ้อง\nหลอมละลายศัตรูที่อยู่ใกล้เคียงด้วยป้อมปืนเลเซอร์อัตโนมัติสี่ป้อม unit.navanax.description = ยิงลูกระเบิดคลื่นชีพจรแม่เหล็กขนาดใหญ่ สร้างความเสียหายอย่างหนักให้กับเครือข่ายพลังงานศัตรู\nและซ่อมแซมสิ่งก่อสร้างของพวกพ้อง\nหลอมละลายศัตรูที่อยู่ใกล้เคียงด้วยป้อมปืนเลเซอร์อัตโนมัติสี่ป้อม

View File

@@ -101,6 +101,7 @@ customgame = Özel Oyun
newgame = Yeni Oyun newgame = Yeni Oyun
none = <yok> none = <yok>
none.found = [lightgray]<Bulunamadı> none.found = [lightgray]<Bulunamadı>
none.inmap = [lightgray]<Haritada Bulunamadı>
minimap = Harita minimap = Harita
position = Pozisyon position = Pozisyon
close = Kapat close = Kapat
@@ -214,6 +215,7 @@ hosts.none = [lightgray]Yerel oyun bulunamadı!
host.invalid = [scarlet]Kurucuya bağlanılamıyor. host.invalid = [scarlet]Kurucuya bağlanılamıyor.
servers.local = Yerel Sunucular servers.local = Yerel Sunucular
servers.local.steam = ık Oyunar & Yerel Sunucular
servers.remote = Uzak Sunucular servers.remote = Uzak Sunucular
servers.global = Topluluk Sunucuları servers.global = Topluluk Sunucuları
@@ -565,6 +567,7 @@ sectors.unexplored = [lightgray]Keşfedilmemiş
sectors.resources = Kaynaklar: sectors.resources = Kaynaklar:
sectors.production = Üretim: sectors.production = Üretim:
sectors.export = İhracat: sectors.export = İhracat:
sectors.import = İthalat:
sectors.time = Zaman: sectors.time = Zaman:
sectors.threat = Tehlike: sectors.threat = Tehlike:
sectors.wave = Dalga: sectors.wave = Dalga:
@@ -806,6 +809,7 @@ bullet.reload = [stat]{0}[lightgray]x atış hızı
unit.blocks = blok unit.blocks = blok
unit.blockssquared = blok² unit.blockssquared = blok²
unit.powersecond = enerji birimi/saniye unit.powersecond = enerji birimi/saniye
unit.tilessecond = alan/saniye
unit.liquidsecond = sıvı birimi/saniye unit.liquidsecond = sıvı birimi/saniye
unit.itemssecond = eşya/saniye unit.itemssecond = eşya/saniye
unit.liquidunits = sıvı birimi unit.liquidunits = sıvı birimi
@@ -871,7 +875,8 @@ setting.saveinterval.name = Kayıt Aralığı
setting.seconds = {0} Saniye setting.seconds = {0} Saniye
setting.milliseconds = {0} milisaniye setting.milliseconds = {0} milisaniye
setting.fullscreen.name = Tam Ekran setting.fullscreen.name = Tam Ekran
setting.borderlesswindow.name = Kenarsız Pencere [lightgray](yeniden açmak gerekebilir) setting.borderlesswindow.name = Kenarsız Pencere
setting.borderlesswindow.description = Oyunu baştan açman gerekebilir.
setting.fps.name = FPS Göster setting.fps.name = FPS Göster
setting.smoothcamera.name = Yumuşak Geçişli Kamera setting.smoothcamera.name = Yumuşak Geçişli Kamera
setting.vsync.name = VSync setting.vsync.name = VSync
@@ -994,6 +999,7 @@ rules.wavetimer = Dalga Zamanlayıcısı
rules.waves = Dalgalar rules.waves = Dalgalar
rules.attack = Saldırı Modu rules.attack = Saldırı Modu
rules.buildai = Yapay Zeka İnşası rules.buildai = Yapay Zeka İnşası
rules.cleanupdeadteams = Kaybeden Takımın Bloklarını Temizle (PvP)
rules.corecapture = Yıkımca Çekirdeği Elegeçir rules.corecapture = Yıkımca Çekirdeği Elegeçir
rules.polygoncoreprotection = Çokgenli Çekirdek Koruması rules.polygoncoreprotection = Çokgenli Çekirdek Koruması
rules.enemyCheat = Sonsuz AI (Kırmızı Takım) Kaynakları rules.enemyCheat = Sonsuz AI (Kırmızı Takım) Kaynakları
@@ -1288,7 +1294,6 @@ block.meltdown.name = Meltdown
block.foreshadow.name = Foreshadow block.foreshadow.name = Foreshadow
block.container.name = Konteyner block.container.name = Konteyner
block.launch-pad.name = Kalkış Pisti block.launch-pad.name = Kalkış Pisti
block.launch-pad-large.name = Büyük Kalkış Pisti
block.segment.name = Segment block.segment.name = Segment
block.command-center.name = Komuta Merkezi block.command-center.name = Komuta Merkezi
block.ground-factory.name = Yer Birimi Fabrikası block.ground-factory.name = Yer Birimi Fabrikası
@@ -1348,6 +1353,7 @@ hint.placeTurret = \uf861 [accent]Silahlar[] seni düşman birimlerinden korumak
hint.breaking = Blokları silmek için silmek istediğiniz objelerin üstüne [accent]Sağ Tıklayın[]. Birden fazla obje silmek için sağ tuşu basılı tutun ve farenizi sürükleyin. hint.breaking = Blokları silmek için silmek istediğiniz objelerin üstüne [accent]Sağ Tıklayın[]. Birden fazla obje silmek için sağ tuşu basılı tutun ve farenizi sürükleyin.
hint.breaking.mobile = Ekranın sağ altındaki \ue817 [accent]çekiç[] tuşuna basın ve silmek istediğiniz objelere tıklayın. \n\nBirden fazla obje silmek için parmağınızı ekranda 1 saniye basılı tutun ve parmağınızı sürükleyin. hint.breaking.mobile = Ekranın sağ altındaki \ue817 [accent]çekiç[] tuşuna basın ve silmek istediğiniz objelere tıklayın. \n\nBirden fazla obje silmek için parmağınızı ekranda 1 saniye basılı tutun ve parmağınızı sürükleyin.
hint.blockInfo = Bir blok hakkında bilgiyi görüntülemek için [accent]inşa menüsüne[] tıklayın. Sonra sağdaki [accent][[?][] sembolüne tıklayın. hint.blockInfo = Bir blok hakkında bilgiyi görüntülemek için [accent]inşa menüsüne[] tıklayın. Sonra sağdaki [accent][[?][] sembolüne tıklayın.
hint.derelict = [accent]Sahipsiz[] binalar artık çalışmaz durumdadır. \n\nBu binaları [accent]yıkarsanız[] size malzeme verirler.
hint.research = \ue875 [accent]Araştırma[] sekmesini kullanarak yeni teknolojiler araştırabilirsiniz. hint.research = \ue875 [accent]Araştırma[] sekmesini kullanarak yeni teknolojiler araştırabilirsiniz.
hint.research.mobile = \ue88c [accent]Menüdeki[] \ue875 [accent]Araştırma[] sekmesini kullanarak yeni teknolojiler araştırabilirsiniz. hint.research.mobile = \ue88c [accent]Menüdeki[] \ue875 [accent]Araştırma[] sekmesini kullanarak yeni teknolojiler araştırabilirsiniz.
hint.unitControl = Kendi takımınızdaki taret ve birimleri kontrol etmek için [accent][[Sol CTRL][] tuşunu basılı tutarak istediğiniz taretin yada birimin üstüne sol tıklayın. hint.unitControl = Kendi takımınızdaki taret ve birimleri kontrol etmek için [accent][[Sol CTRL][] tuşunu basılı tutarak istediğiniz taretin yada birimin üstüne sol tıklayın.
@@ -1369,8 +1375,6 @@ hint.generator = \uf879 [accent]Termik Jeneratör[] kömür yakarak enerji üret
hint.guardian = [accent]Gardiyan[] birimleri güçlü bir zırha sahiptir. [accent]bakır[] ve [accent]kurşun[] gibi mermilere karşı [scarlet]Dayanıklıdır[].\n\nGardiyanları öldürmek için [accent]salvo[] gibi daha güçlü taretleri ve \uf835 [accent]grafit[] gibi daha çok hasar veren mermileri kullanın. hint.guardian = [accent]Gardiyan[] birimleri güçlü bir zırha sahiptir. [accent]bakır[] ve [accent]kurşun[] gibi mermilere karşı [scarlet]Dayanıklıdır[].\n\nGardiyanları öldürmek için [accent]salvo[] gibi daha güçlü taretleri ve \uf835 [accent]grafit[] gibi daha çok hasar veren mermileri kullanın.
hint.coreUpgrade = Merkezinizi, [accent]merkezinizin üstüne daha gelişmiş bir merkez[] koyarak geliştirebilirsiniz. \n\n[accent]Parçacık[] olarak adlandırılan fakirhanenizin üstüne [accent]Temel[] olarak adlandırılan merkezinizi koyun. Merkezinizin etrafında hiçbir yapı olmamalıdır. hint.coreUpgrade = Merkezinizi, [accent]merkezinizin üstüne daha gelişmiş bir merkez[] koyarak geliştirebilirsiniz. \n\n[accent]Parçacık[] olarak adlandırılan fakirhanenizin üstüne [accent]Temel[] olarak adlandırılan merkezinizi koyun. Merkezinizin etrafında hiçbir yapı olmamalıdır.
hint.presetLaunch = [accent]Donmuş Ormanlar[] gibi [accent]ana sektörlere iniş[] herhangi bir yerden yapılabilir. Yakındaki bir sektörden fırlatma gerektirmez.\n\nBunun gibi [accent]sayı ile isimlendirilmiş[] sektörleri ele geçirmek [accent]isteğe bağlıdır.[]. hint.presetLaunch = [accent]Donmuş Ormanlar[] gibi [accent]ana sektörlere iniş[] herhangi bir yerden yapılabilir. Yakındaki bir sektörden fırlatma gerektirmez.\n\nBunun gibi [accent]sayı ile isimlendirilmiş[] sektörleri ele geçirmek [accent]isteğe bağlıdır.[].
hint.coreUpgrade = Bir çekirdeğin Üstüne başka bir çekirdek koayarak onu geliştirebilirsin!\n\n Daha gelişmiş çekirdekler daha fazla kapasite demektir.
hint.presetLaunch = Hikaye Sektörlerine her yerden fırltış yapabilirsin! Ancak Numaralı Sektörlere temas olmadan Fırlatış yapılamaz.
hint.coreIncinerate = Bir çekirdek ağzına kadar dolduktan sonra, ekstra itemler [accent]eritilir[]. hint.coreIncinerate = Bir çekirdek ağzına kadar dolduktan sonra, ekstra itemler [accent]eritilir[].
hint.coopCampaign = Arkadaşlarınla Multiplayer Campaign oynarken, her yaptığınız Araştırma ve item aktarımı, senin oyun içi Campaign ine de aktarılır. hint.coopCampaign = Arkadaşlarınla Multiplayer Campaign oynarken, her yaptığınız Araştırma ve item aktarımı, senin oyun içi Campaign ine de aktarılır.
#Yukarıdaki bağzı cümleler Anti Dragon tarafından çevirildi. #Yukarıdaki bağzı cümleler Anti Dragon tarafından çevirildi.
@@ -1401,6 +1405,7 @@ liquid.slag.description = Çeşitli tipte erimiş metallerin birbirine karışı
liquid.oil.description = İleri seviye malzeme üretiminde kullanılan bir sıvıdır. Yakıt olarak kömür haline getirilebilir veya püskürtülüp ateşe verilerek bir silah olarak kullanılabilir. liquid.oil.description = İleri seviye malzeme üretiminde kullanılan bir sıvıdır. Yakıt olarak kömür haline getirilebilir veya püskürtülüp ateşe verilerek bir silah olarak kullanılabilir.
liquid.cryofluid.description = Su ve titanyumdan oluşturulan inaktif bir sıvı. Son derece yüksek ısı kapasitesine sahiptir. Soğutucu olarak yaygın olarak kullanılır. liquid.cryofluid.description = Su ve titanyumdan oluşturulan inaktif bir sıvı. Son derece yüksek ısı kapasitesine sahiptir. Soğutucu olarak yaygın olarak kullanılır.
block.derelict = [lightgray] Sahipsiz
block.resupply-point.description = Yakındaki birimlere mermi verir. Elektikle çalışmaz. block.resupply-point.description = Yakındaki birimlere mermi verir. Elektikle çalışmaz.
block.armored-conveyor.description = Materyalleri titanyum konveyörlerle aynı hızda taşır ama daha fazla zırha sahiptir. Diğer konveyörler dışında yan taraflardan materyal kabul etmez. block.armored-conveyor.description = Materyalleri titanyum konveyörlerle aynı hızda taşır ama daha fazla zırha sahiptir. Diğer konveyörler dışında yan taraflardan materyal kabul etmez.
block.illuminator.description = Küçük, kompakt, yapılandırılabilir bir ışık kaynağı. Çalışması için enerji gerekir. block.illuminator.description = Küçük, kompakt, yapılandırılabilir bir ışık kaynağı. Çalışması için enerji gerekir.
@@ -1504,7 +1509,6 @@ block.vault.description = Her materyalden az miktarda saklar. Materyalleri kasad
block.container.description = Her materyalden az miktarda saklar. Materyalleri konteynerden almak için bir boşaltıcı bloğu kullanılabilir. block.container.description = Her materyalden az miktarda saklar. Materyalleri konteynerden almak için bir boşaltıcı bloğu kullanılabilir.
block.unloader.description = Materyalleri bir konteyner, kasa, veya çekirdekten çıkarıp; bir konveyöre veya dibindeki bir bloğa koyar. Çıkardığı materyal türü dokunularak değiştirilebilir. block.unloader.description = Materyalleri bir konteyner, kasa, veya çekirdekten çıkarıp; bir konveyöre veya dibindeki bir bloğa koyar. Çıkardığı materyal türü dokunularak değiştirilebilir.
block.launch-pad.description = Başka Bir Sektöre item gönderir. block.launch-pad.description = Başka Bir Sektöre item gönderir.
block.launch-pad-large.description = Kalkış pistinin daha gelişmiş bir versiyonu. Daha fazla materyali daha sık gönderebilir.
block.duo.description = Küçük, ucuz bir taret. Yer birimlerine karşı etkilidir. block.duo.description = Küçük, ucuz bir taret. Yer birimlerine karşı etkilidir.
block.scatter.description = Önemli bir uçaksavar tareti. Düşman birimlerine hurda ya da kurşun uçaksavar mermileri atar. block.scatter.description = Önemli bir uçaksavar tareti. Düşman birimlerine hurda ya da kurşun uçaksavar mermileri atar.
block.scorch.description = Etrafındaki düşmanları ateşe verir. Yakın mesafede çok etkilidir. block.scorch.description = Etrafındaki düşmanları ateşe verir. Yakın mesafede çok etkilidir.
@@ -1519,6 +1523,7 @@ block.ripple.description = Çok güçlü bir havan tareti. Uzak mesafedeki düş
block.cyclone.description = Büyük bir anti hava ve anti kara tareti. Yakınındaki düşmanlara patlayıcı uçaksavar mermi kümeleri atar. block.cyclone.description = Büyük bir anti hava ve anti kara tareti. Yakınındaki düşmanlara patlayıcı uçaksavar mermi kümeleri atar.
block.spectre.description = Dev bir çift namlulu top. Hava ve kara birimlerine iri, zırh delici mermiler atar. block.spectre.description = Dev bir çift namlulu top. Hava ve kara birimlerine iri, zırh delici mermiler atar.
block.meltdown.description = Dev bir lazer topu. Yüklenip yakındaki düşmanlara uzun süreli lazer ışınları yollar. Çalışması için soğutucu gerekir. block.meltdown.description = Dev bir lazer topu. Yüklenip yakındaki düşmanlara uzun süreli lazer ışınları yollar. Çalışması için soğutucu gerekir.
block.foreshadow.description = Çok uzaktaki Tek bir hedefe inanılmaz güçlü bir şok ışını vurur. En fazla canı olan elemanı hedef alır.
block.repair-point.description = Kendisine en yakın hasarlı birimi tamir eder. block.repair-point.description = Kendisine en yakın hasarlı birimi tamir eder.
block.segment.description = Gelen mermilere zarar verir ve onları yok eder. Lazer mermilere etki etmez. block.segment.description = Gelen mermilere zarar verir ve onları yok eder. Lazer mermilere etki etmez.
block.parallax.description = Çekici bir ışın fırlatarak hava düşmanlarını kendine çeker. Onlara az da olsa zarar verir. block.parallax.description = Çekici bir ışın fırlatarak hava düşmanlarını kendine çeker. Onlara az da olsa zarar verir.
@@ -1545,6 +1550,8 @@ block.memory-bank.description = Bilgi saklar. Yüksek kapasiteye sahiptir.
block.logic-display.description = Bir işlemciden bilgi alarak grafik gösteririr. block.logic-display.description = Bir işlemciden bilgi alarak grafik gösteririr.
block.large-logic-display.description = Bir işlemciden bilgi alarak grafik gösteririr. block.large-logic-display.description = Bir işlemciden bilgi alarak grafik gösteririr.
block.interplanetary-accelerator.description = Gezegenler Arası ulaşım şimdi parmaklarının ucunda... block.interplanetary-accelerator.description = Gezegenler Arası ulaşım şimdi parmaklarının ucunda...
block.repair-turret.description = Sürekli en yakın elemanı tamir eder. Soğutucu kullanabilir.
block.payload-propulsion-tower.description = Kütle sürücü gibi bir yerden başka bir yere fırlatır, ancak malzeme yerine yük fırlatmakta kullanılır.
#burdan sonraki her şeyi benim translate etmem gerekti!!! -RTOmega #burdan sonraki her şeyi benim translate etmem gerekti!!! -RTOmega
unit.dagger.description = Düşmanlara basit mermilerle ateş eder. unit.dagger.description = Düşmanlara basit mermilerle ateş eder.
unit.mace.description = Düşmanlara alev atar. unit.mace.description = Düşmanlara alev atar.
@@ -1579,6 +1586,11 @@ unit.omura.description = Uzun menzil bir ışın atıcıya sahiptir. Mermisi ner
unit.alpha.description = Çekirdeği korur. Bina inşa eder. unit.alpha.description = Çekirdeği korur. Bina inşa eder.
unit.beta.description = Çekirdeği korur. Bina inşa eder. unit.beta.description = Çekirdeği korur. Bina inşa eder.
unit.gamma.description = Çekirdeği korur. Bina inşa eder. unit.gamma.description = Çekirdeği korur. Bina inşa eder.
unit.retusa.description = Sensörlü mayın döşer. Yakındakileri tamir eder.
unit.oxynoe.description = Tamir edici ateş fırlatır. Düşman mermilerini havada vurur.
unit.cyerce.description = Takipçi toplu füze atar. Yakındakileri tamir eder.
unit.aegires.description = Enerji alanına giren düşmanları şoklar. Yakındakileri tamir eder.
unit.navanax.description = Devasa patlayıcı EMP gülleleri fırlatır, düşman elektir sistemlerini yok eder ve müttefiklerini tamir eder. Yaklaşan düşmanları 4 mini oto-laser turreti ile eritir.
lst.read = Bağlı hafıza kutusundaki numarayı okur. lst.read = Bağlı hafıza kutusundaki numarayı okur.
lst.write = Bağlı hafıza kutuaundaki numaraya yazar. lst.write = Bağlı hafıza kutuaundaki numaraya yazar.
@@ -1593,6 +1605,8 @@ lst.sensor = Bloklardan bilgi alır.
lst.set = Bir değişken ata. lst.set = Bir değişken ata.
lst.operation = Değişkenlerle işlem yap. lst.operation = Değişkenlerle işlem yap.
lst.end = Döngünün sonuna atla. lst.end = Döngünün sonuna atla.
lst.wait = Belli süre bekler.
lst.lookup = ID kullanarak herhangi bir blok,eleman,bina vs ye bak.\nToplam sayı kullanımı:\n[accent]@unitCount[] / [accent]@itemCount[] / [accent]@liquidCount[] / [accent]@blockCount[]
lst.jump = Bir yerden başka bir yere atla. lst.jump = Bir yerden başka bir yere atla.
lst.unitbind = Bir birimi bağla: [accent]@unit[]. lst.unitbind = Bir birimi bağla: [accent]@unit[].
lst.unitcontrol = Bağlı birimi kontrol et. lst.unitcontrol = Bağlı birimi kontrol et.

View File

@@ -353,3 +353,6 @@
63353=silicon-arc-furnace|block-silicon-arc-furnace-ui 63353=silicon-arc-furnace|block-silicon-arc-furnace-ui
63352=metal-floor-4|block-metal-floor-4-ui 63352=metal-floor-4|block-metal-floor-4-ui
63351=invincible|status-invincible-ui 63351=invincible|status-invincible-ui
63356=sharded|team-sharded
63357=crux|team-crux
63358=derelict|team-derelict

View File

@@ -13,7 +13,6 @@ import mindustry.game.Teams.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.world.*; import mindustry.world.*;
import mindustry.world.blocks.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import java.util.*; import java.util.*;
@@ -32,7 +31,7 @@ public class BlockIndexer{
/** Stores all ore quadrants on the map. Maps ID to qX to qY to a list of tiles with that ore. */ /** Stores all ore quadrants on the map. Maps ID to qX to qY to a list of tiles with that ore. */
private IntSeq[][][] ores; private IntSeq[][][] ores;
/** Stores all damaged tile entities by team. */ /** Stores all damaged tile entities by team. */
private ObjectSet<Building>[] damagedTiles = new ObjectSet[Team.all.length]; private Seq<Building>[] damagedTiles = new Seq[Team.all.length];
/** All ores available on this map. */ /** All ores available on this map. */
private ObjectSet<Item> allOres = new ObjectSet<>(); private ObjectSet<Item> allOres = new ObjectSet<>();
/** Stores teams that are present here as tiles. */ /** Stores teams that are present here as tiles. */
@@ -59,7 +58,7 @@ public class BlockIndexer{
}); });
Events.on(WorldLoadEvent.class, event -> { Events.on(WorldLoadEvent.class, event -> {
damagedTiles = new ObjectSet[Team.all.length]; damagedTiles = new Seq[Team.all.length];
flagMap = new TileArray[Team.all.length][BlockFlag.all.length]; flagMap = new TileArray[Team.all.length][BlockFlag.all.length];
activeTeams = new Seq<>(Team.class); activeTeams = new Seq<>(Team.class);
@@ -74,10 +73,6 @@ public class BlockIndexer{
for(Tile tile : world.tiles){ for(Tile tile : world.tiles){
process(tile); process(tile);
if(tile.build != null && tile.build.damaged()){
notifyTileDamaged(tile.build);
}
var drop = tile.drop(); var drop = tile.drop();
if(drop != null){ if(drop != null){
@@ -104,6 +99,7 @@ public class BlockIndexer{
public void removeIndex(Tile tile){ public void removeIndex(Tile tile){
var team = tile.team(); var team = tile.team();
if(tile.build != null && tile.isCenter()){ if(tile.build != null && tile.isCenter()){
var build = tile.build;
var flags = tile.block().flags; var flags = tile.block().flags;
var data = team.data(); var data = team.data();
@@ -118,7 +114,15 @@ public class BlockIndexer{
//unregister building from building quadtree //unregister building from building quadtree
if(data.buildings != null){ if(data.buildings != null){
data.buildings.remove(tile.build); data.buildings.remove(build);
}
//is no longer registered
build.wasDamaged = false;
//unregister damaged buildings
if(build.damaged() && damagedTiles[team.id] != null){
damagedTiles[team.id].remove(build);
} }
} }
} }
@@ -175,25 +179,12 @@ public class BlockIndexer{
} }
/** Returns all damaged tiles by team. */ /** Returns all damaged tiles by team. */
public ObjectSet<Building> getDamaged(Team team){ public Seq<Building> getDamaged(Team team){
breturnArray.clear();
if(damagedTiles[team.id] == null){ if(damagedTiles[team.id] == null){
damagedTiles[team.id] = new ObjectSet<>(); return damagedTiles[team.id] = new Seq<>(false);
} }
ObjectSet<Building> set = damagedTiles[team.id]; return damagedTiles[team.id];
for(Building build : set){
if((!build.isValid() || build.team != team || !build.damaged()) || build.block instanceof ConstructBlock){
breturnArray.add(build);
}
}
for(Building tile : breturnArray){
set.remove(tile);
}
return set;
} }
/** Get all allied blocks with a flag. */ /** Get all allied blocks with a flag. */
@@ -271,12 +262,22 @@ public class BlockIndexer{
return returnArray; return returnArray;
} }
public void notifyTileDamaged(Building entity){ public void notifyBuildHealed(Building build){
if(damagedTiles[entity.team.id] == null){ if(build.wasDamaged && !build.damaged() && damagedTiles[build.team.id] != null){
damagedTiles[entity.team.id] = new ObjectSet<>(); damagedTiles[build.team.id].remove(build);
build.wasDamaged = false;
}
}
public void notifyBuildDamaged(Building build){
if(build.wasDamaged || !build.damaged()) return;
if(damagedTiles[build.team.id] == null){
damagedTiles[build.team.id] = new Seq<>(false);
} }
damagedTiles[entity.team.id].add(entity); damagedTiles[build.team.id].add(build);
build.wasDamaged = true;
} }
public void allBuildings(float x, float y, float range, Cons<Building> cons){ public void allBuildings(float x, float y, float range, Cons<Building> cons){
@@ -417,6 +418,8 @@ public class BlockIndexer{
data.buildings = new QuadTree<>(new Rect(0, 0, world.unitWidth(), world.unitHeight())); data.buildings = new QuadTree<>(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
} }
data.buildings.insert(tile.build); data.buildings.insert(tile.build);
notifyBuildDamaged(tile.build);
} }
if(!tile.block().isStatic()){ if(!tile.block().isStatic()){

View File

@@ -175,16 +175,6 @@ public class Formation{
return -1; return -1;
} }
// debug
public SlotAssignment getSlotAssignmentAt(int index){
return slotAssignments.get(index);
}
// debug
public int getSlotAssignmentCount(){
return slotAssignments.size;
}
/** Writes new slot locations to each member */ /** Writes new slot locations to each member */
public void updateSlots(){ public void updateSlots(){
positionOffset.set(anchor); positionOffset.set(anchor);

View File

@@ -102,7 +102,7 @@ public class LogicAI extends AIController{
} }
//look where moving if there's nothing to aim at //look where moving if there's nothing to aim at
if(!shoot){ if(!shoot || !unit.type.omniMovement){
unit.lookAt(unit.prefRotation()); unit.lookAt(unit.prefRotation());
}else if(unit.hasWeapons() && unit.mounts.length > 0 && !unit.mounts[0].weapon.ignoreRotation){ //if there is, look at the object }else if(unit.hasWeapons() && unit.mounts.length > 0 && !unit.mounts[0].weapon.ignoreRotation){ //if there is, look at the object
unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY); unit.lookAt(unit.mounts[0].aimX, unit.mounts[0].aimY);
@@ -131,7 +131,13 @@ public class LogicAI extends AIController{
//do not move when infinite vectors are used. //do not move when infinite vectors are used.
if(vec.isNaN() || vec.isInfinite()) return; if(vec.isNaN() || vec.isInfinite()) return;
unit.approach(vec); if(unit.type.omniMovement){
unit.approach(vec);
}else{
unit.rotateMove(vec);
}
} }
@Override @Override

View File

@@ -2,6 +2,7 @@ package mindustry.async;
import arc.*; import arc.*;
import arc.struct.*; import arc.struct.*;
import arc.util.async.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import java.util.concurrent.*; import java.util.concurrent.*;
@@ -49,7 +50,7 @@ public class AsyncCore{
executor = Executors.newFixedThreadPool(processes.size, r -> { executor = Executors.newFixedThreadPool(processes.size, r -> {
Thread thread = new Thread(r, "AsyncLogic-Thread"); Thread thread = new Thread(r, "AsyncLogic-Thread");
thread.setDaemon(true); thread.setDaemon(true);
thread.setUncaughtExceptionHandler((t, e) -> Core.app.post(() -> { throw new RuntimeException(e); })); thread.setUncaughtExceptionHandler((t, e) -> Threads.throwAppException(e));
return thread; return thread;
}); });
} }

View File

@@ -702,7 +702,9 @@ public class Blocks implements ContentList{
craftTime = 40f; craftTime = 40f;
updateEffect = Fx.pulverizeSmall; updateEffect = Fx.pulverizeSmall;
hasItems = hasPower = true; hasItems = hasPower = true;
drawer = new DrawRotator(); drawer = new DrawRotator(){{
drawSpinSprite = true;
}};
ambientSound = Sounds.grinding; ambientSound = Sounds.grinding;
ambientSoundVolume = 0.025f; ambientSoundVolume = 0.025f;
@@ -1295,6 +1297,7 @@ public class Blocks implements ContentList{
drillEffect = Fx.mineHuge; drillEffect = Fx.mineHuge;
rotateSpeed = 6f; rotateSpeed = 6f;
warmupSpeed = 0.01f; warmupSpeed = 0.01f;
itemCapacity = 20;
//more than the laser drill //more than the laser drill
liquidBoostIntensity = 1.8f; liquidBoostIntensity = 1.8f;

View File

@@ -130,7 +130,7 @@ public class Fx{
Fill.circle(x, y, e.fslope() * 1.5f * size); Fill.circle(x, y, e.fslope() * 1.5f * size);
}), }),
pointBeam = new Effect(25f, e -> { pointBeam = new Effect(25f, 300f, e -> {
if(!(e.data instanceof Position)) return; if(!(e.data instanceof Position)) return;
Position pos = e.data(); Position pos = e.data();

View File

@@ -16,12 +16,12 @@ public class Puddles{
/** Deposits a Puddle between tile and source. */ /** Deposits a Puddle between tile and source. */
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){ public static void deposit(Tile tile, Tile source, Liquid liquid, float amount){
deposit(tile, source, liquid, amount, 0); deposit(tile, source, liquid, amount, true);
} }
/** Deposits a Puddle at a tile. */ /** Deposits a Puddle at a tile. */
public static void deposit(Tile tile, Liquid liquid, float amount){ public static void deposit(Tile tile, Liquid liquid, float amount){
deposit(tile, tile, liquid, amount, 0); deposit(tile, tile, liquid, amount, true);
} }
/** Returns the Puddle on the specified tile. May return null. */ /** Returns the Puddle on the specified tile. May return null. */
@@ -29,7 +29,7 @@ public class Puddles{
return map.get(tile.pos()); return map.get(tile.pos());
} }
public static void deposit(Tile tile, Tile source, Liquid liquid, float amount, int generation){ public static void deposit(Tile tile, Tile source, Liquid liquid, float amount, boolean initial){
if(tile == null) return; if(tile == null) return;
if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){ if(tile.floor().isLiquid && !canStayOn(liquid, tile.floor().liquidDrop)){
@@ -38,16 +38,14 @@ public class Puddles{
Puddle p = map.get(tile.pos()); Puddle p = map.get(tile.pos());
if(generation == 0 && p != null && p.lastRipple <= Time.time - 40f){ if(initial && p != null && p.lastRipple <= Time.time - 40f){
Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, tile.floor().liquidDrop.color); Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, tile.floor().liquidDrop.color);
p.lastRipple = Time.time; p.lastRipple = Time.time;
} }
return; return;
} }
if(tile.floor().solid){ if(tile.floor().solid) return;
return;
}
Puddle p = map.get(tile.pos()); Puddle p = map.get(tile.pos());
if(p == null){ if(p == null){
@@ -55,14 +53,13 @@ public class Puddles{
puddle.tile = tile; puddle.tile = tile;
puddle.liquid = liquid; puddle.liquid = liquid;
puddle.amount = amount; puddle.amount = amount;
puddle.generation = generation;
puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f); puddle.set((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f);
puddle.add(); puddle.add();
map.put(tile.pos(), puddle); map.put(tile.pos(), puddle);
}else if(p.liquid == liquid){ }else if(p.liquid == liquid){
p.accepting = Math.max(amount, p.accepting); p.accepting = Math.max(amount, p.accepting);
if(generation == 0 && p.lastRipple <= Time.time - 40f && p.amount >= maxLiquid / 2f){ if(initial && p.lastRipple <= Time.time - 40f && p.amount >= maxLiquid / 2f){
Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, p.liquid.color); Fx.ripple.at((tile.worldx() + source.worldx()) / 2f, (tile.worldy() + source.worldy()) / 2f, 1f, p.liquid.color);
p.lastRipple = Time.time; p.lastRipple = Time.time;
} }

View File

@@ -143,7 +143,7 @@ public class Units{
/** Returns the nearest damaged tile. */ /** Returns the nearest damaged tile. */
public static Building findDamagedTile(Team team, float x, float y){ public static Building findDamagedTile(Team team, float x, float y){
return Geometry.findClosest(x, y, indexer.getDamaged(team)); return indexer.getDamaged(team).min(b -> b.dst2(x, y));
} }
/** Returns the nearest ally tile in a range. */ /** Returns the nearest ally tile in a range. */

View File

@@ -96,7 +96,7 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
if(!(tile.build instanceof ConstructBuild cb)){ if(!(tile.build instanceof ConstructBuild cb)){
if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){ if(!current.initialized && !current.breaking && Build.validPlace(current.block, team, current.x, current.y, current.rotation)){
boolean hasAll = infinite || current.isRotation(team) || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item, Mathf.round(i.amount * state.rules.buildCostMultiplier))); boolean hasAll = infinite || current.isRotation(team) || !Structs.contains(current.block.requirements, i -> core != null && !core.items.has(i.item, Math.min(Mathf.round(i.amount * state.rules.buildCostMultiplier), 1)));
if(hasAll){ if(hasAll){
Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation); Call.beginPlace(self(), current.block, team, current.x, current.y, current.rotation);

View File

@@ -63,6 +63,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
transient boolean enabled = true; transient boolean enabled = true;
transient float enabledControlTime; transient float enabledControlTime;
transient String lastAccessed; transient String lastAccessed;
transient boolean wasDamaged; //used only by the indexer
PowerModule power; PowerModule power;
ItemModule items; ItemModule items;
@@ -1071,9 +1072,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
} }
public String getDisplayName(){ public String getDisplayName(){
//derelict team icon currently doesn't display
return team == Team.derelict ? return team == Team.derelict ?
block.localizedName + "\n" + Core.bundle.get("block.derelict"): block.localizedName + "\n" + Core.bundle.get("block.derelict") :
block.localizedName; block.localizedName + (team == player.team() || team.emoji.isEmpty() ? "" : " " + team.emoji);
} }
public TextureRegion getDisplayIcon(){ public TextureRegion getDisplayIcon(){
@@ -1344,6 +1346,18 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
return tile.build == self() && !dead(); return tile.build == self() && !dead();
} }
@MethodPriority(100)
@Override
public void heal(){
indexer.notifyBuildHealed(self());
}
@MethodPriority(100)
@Override
public void heal(float amount){
indexer.notifyBuildHealed(self());
}
@Override @Override
public float hitSize(){ public float hitSize(){
return tile.block().size * tilesize; return tile.block().size * tilesize;

View File

@@ -81,7 +81,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
} }
public boolean hasCollided(int id){ public boolean hasCollided(int id){
return collided.size != 0 && !collided.contains(id); return collided.size != 0 && collided.contains(id);
} }
@Replace @Replace

View File

@@ -20,7 +20,6 @@ import static mindustry.entities.Puddles.*;
@EntityDef(value = {Puddlec.class}, pooled = true) @EntityDef(value = {Puddlec.class}, pooled = true)
@Component(base = true) @Component(base = true)
abstract class PuddleComp implements Posc, Puddlec, Drawc{ abstract class PuddleComp implements Posc, Puddlec, Drawc{
private static final int maxGeneration = 2;
private static final Rect rect = new Rect(), rect2 = new Rect(); private static final Rect rect = new Rect(), rect2 = new Rect();
private static int seeds; private static int seeds;
@@ -29,7 +28,6 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
transient float accepting, updateTime, lastRipple; transient float accepting, updateTime, lastRipple;
float amount; float amount;
int generation;
Tile tile; Tile tile;
Liquid liquid; Liquid liquid;
@@ -39,22 +37,23 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
@Override @Override
public void update(){ public void update(){
//update code
float addSpeed = accepting > 0 ? 3f : 0f; float addSpeed = accepting > 0 ? 3f : 0f;
amount -= Time.delta * (1f - liquid.viscosity) / (5f + addSpeed); amount -= Time.delta * (1f - liquid.viscosity) / (5f + addSpeed);
amount += accepting; amount += accepting;
accepting = 0f; accepting = 0f;
if(amount >= maxLiquid / 1.5f && generation < maxGeneration){ if(amount >= maxLiquid / 1.5f){
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta; float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Time.delta;
int targets = 0;
for(Point2 point : Geometry.d4){ for(Point2 point : Geometry.d4){
Tile other = world.tile(tile.x + point.x, tile.y + point.y); Tile other = world.tile(tile.x + point.x, tile.y + point.y);
if(other != null && other.block() == Blocks.air){ if(other != null && other.block() == Blocks.air){
Puddles.deposit(other, tile, liquid, deposited, generation + 1); targets ++;
amount -= deposited / 2f; //tweak to speed up/slow down Puddle propagation Puddles.deposit(other, tile, liquid, deposited, false);
} }
} }
amount -= deposited * targets;
} }
amount = Mathf.clamp(amount, 0, maxLiquid); amount = Mathf.clamp(amount, 0, maxLiquid);

View File

@@ -59,6 +59,14 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
vel.approachDelta(vector, type.accel * realSpeed()); vel.approachDelta(vector, type.accel * realSpeed());
} }
public void rotateMove(Vec2 vec){
moveAt(Tmp.v2.trns(rotation, vec.len()));
if(!vec.isZero()){
rotation = Angles.moveToward(rotation, vec.angle(), type.rotateSpeed * Math.max(Time.delta, 1));
}
}
public void aimLook(Position pos){ public void aimLook(Position pos){
aim(pos); aim(pos);
lookAt(pos); lookAt(pos);
@@ -126,6 +134,9 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
if(isBuilding()){ if(isBuilding()){
return state.rules.infiniteResources ? Float.MAX_VALUE : Math.max(type.clipSize, type.region.width) + buildingRange + tilesize*4f; return state.rules.infiniteResources ? Float.MAX_VALUE : Math.max(type.clipSize, type.region.width) + buildingRange + tilesize*4f;
} }
if(mining()){
return type.clipSize + type.miningRange;
}
return type.clipSize; return type.clipSize;
} }

View File

@@ -114,6 +114,7 @@ public class Schematics implements Loadable{
target.tiles.addAll(newSchematic.tiles); target.tiles.addAll(newSchematic.tiles);
target.width = newSchematic.width; target.width = newSchematic.width;
target.height = newSchematic.height; target.height = newSchematic.height;
newSchematic.labels = target.labels;
newSchematic.tags.putAll(target.tags); newSchematic.tags.putAll(target.tags);
newSchematic.file = target.file; newSchematic.file = target.file;

View File

@@ -1,5 +1,6 @@
package mindustry.game; package mindustry.game;
import arc.func.*;
import arc.math.*; import arc.math.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
@@ -21,6 +22,7 @@ public class SectorInfo{
private static final int valueWindow = 60; private static final int valueWindow = 60;
/** refresh period of export in ticks */ /** refresh period of export in ticks */
private static final float refreshPeriod = 60; private static final float refreshPeriod = 60;
private static float returnf;
/** Core input statistics. */ /** Core input statistics. */
public ObjectMap<Item, ExportStat> production = new ObjectMap<>(); public ObjectMap<Item, ExportStat> production = new ObjectMap<>();
@@ -265,23 +267,29 @@ public class SectorInfo{
return map; return map;
} }
public boolean anyExports(){
if(export.size == 0) return false;
returnf = 0f;
export.each((i, e) -> returnf += e.mean);
return returnf >= 0.01f;
}
/** @return a newly allocated map with import statistics. Use sparingly. */ /** @return a newly allocated map with import statistics. Use sparingly. */
//TODO this can be a float map //TODO this can be a float map
public ObjectMap<Item, ExportStat> importStats(){ public ObjectMap<Item, ExportStat> importStats(Planet planet){
ObjectMap<Item, ExportStat> imports = new ObjectMap<>(); ObjectMap<Item, ExportStat> imports = new ObjectMap<>();
//for all sectors on all planets that have bases and export to this sector eachImport(planet, sector -> sector.info.export.each((item, stat) -> imports.get(item, ExportStat::new).mean += stat.mean));
for(Planet planet : content.planets()){ return imports;
for(Sector sector : planet.sectors){ }
Sector dest = sector.info.getRealDestination();
if(sector.hasBase() && sector.info != this && dest != null && dest.info == this){ /** Iterates through every sector this one imports from. */
//add their exports to our imports public void eachImport(Planet planet, Cons<Sector> cons){
sector.info.export.each((item, stat) -> { for(Sector sector : planet.sectors){
imports.get(item, ExportStat::new).mean += stat.mean; Sector dest = sector.info.getRealDestination();
}); if(sector.hasBase() && sector.info != this && dest != null && dest.info == this){
} cons.get(sector);
} }
} }
return imports;
} }
public static class ExportStat{ public static class ExportStat{

View File

@@ -17,6 +17,8 @@ public class Team implements Comparable<Team>{
public final int id; public final int id;
public final Color color; public final Color color;
public final Color[] palette; public final Color[] palette;
public final int[] palettei = new int[3];
public String emoji = "";
public boolean hasPalette; public boolean hasPalette;
public String name; public String name;
@@ -31,9 +33,9 @@ public class Team implements Comparable<Team>{
Color.valueOf("ffd37f"), Color.valueOf("eab678"), Color.valueOf("d4816b")), Color.valueOf("ffd37f"), Color.valueOf("eab678"), Color.valueOf("d4816b")),
crux = new Team(2, "crux", Color.valueOf("f25555"), crux = new Team(2, "crux", Color.valueOf("f25555"),
Color.valueOf("fc8e6c"), Color.valueOf("f25555"), Color.valueOf("a04553")), Color.valueOf("fc8e6c"), Color.valueOf("f25555"), Color.valueOf("a04553")),
green = new Team(3, "green", Color.valueOf("54d67d")), green = new Team(3, "green", Color.valueOf("54d67d"), Color.valueOf("96f58c"), Color.valueOf("54d67d"), Color.valueOf("28785c")),
purple = new Team(4, "purple", Color.valueOf("995bb0")), purple = new Team(4, "purple", Color.valueOf("995bb0"), Color.valueOf("f08dd5"), Color.valueOf("995bb0"), Color.valueOf("312c63")),
blue = new Team(5, "blue", Color.valueOf("5a4deb")); blue = new Team(5, "blue", Color.valueOf("554deb"), Color.valueOf("80aaff"), Color.valueOf("554deb"), Color.valueOf("3f207d"));
static{ static{
Mathf.rand.setSeed(8); Mathf.rand.setSeed(8);
@@ -60,6 +62,10 @@ public class Team implements Comparable<Team>{
palette[0] = color; palette[0] = color;
palette[1] = color.cpy().mul(0.75f); palette[1] = color.cpy().mul(0.75f);
palette[2] = color.cpy().mul(0.5f); palette[2] = color.cpy().mul(0.5f);
for(int i = 0; i < 3; i++){
palettei[i] = palette[i].rgba();
}
} }
/** Specifies a 3-color team palette. */ /** Specifies a 3-color team palette. */
@@ -69,6 +75,9 @@ public class Team implements Comparable<Team>{
palette[0] = pal1; palette[0] = pal1;
palette[1] = pal2; palette[1] = pal2;
palette[2] = pal3; palette[2] = pal3;
for(int i = 0; i < 3; i++){
palettei[i] = palette[i].rgba();
}
hasPalette = true; hasPalette = true;
} }

View File

@@ -645,6 +645,8 @@ public class DesktopInput extends InputHandler{
if(omni){ if(omni){
unit.moveAt(movement); unit.moveAt(movement);
}else{ }else{
unit.rotateMove(movement);
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
//problem: actual unit rotation is controlled by velocity, but velocity is 1) unpredictable and 2) can be set to 0 //problem: actual unit rotation is controlled by velocity, but velocity is 1) unpredictable and 2) can be set to 0

View File

@@ -922,10 +922,7 @@ public class MobileInput extends InputHandler implements GestureListener{
if(omni){ if(omni){
unit.moveAt(movement); unit.moveAt(movement);
}else{ }else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len())); unit.rotateMove(movement);
if(!movement.isZero()){
unit.rotation = Angles.moveToward(unit.rotation, movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1));
}
} }
//update shooting if not building + not mining //update shooting if not building + not mining

View File

@@ -214,7 +214,8 @@ public class JsonIO{
String str = jsonData.asString(); String str = jsonData.asString();
Item item = Vars.content.getByName(ContentType.item, str); Item item = Vars.content.getByName(ContentType.item, str);
Liquid liquid = Vars.content.getByName(ContentType.liquid, str); Liquid liquid = Vars.content.getByName(ContentType.liquid, str);
return item != null ? item : liquid; Block block = Vars.content.getByName(ContentType.block, str);
return item != null ? item : liquid == null ? block : liquid;
} }
}); });

View File

@@ -420,6 +420,8 @@ public class Maps{
writeCache(map); writeCache(map);
}catch(Exception e){ }catch(Exception e){
e.printStackTrace(); e.printStackTrace();
}finally{
pix.dispose();
} }
}); });
}catch(Exception e){ }catch(Exception e){

View File

@@ -496,7 +496,7 @@ public class SectorDamage{
other.build.addPlan(false); other.build.addPlan(false);
other.remove(); other.remove();
}else{ }else{
indexer.notifyTileDamaged(other.build); indexer.notifyBuildDamaged(other.build);
} }
}else if(other.solid() && !other.synthetic()){ //skip damage propagation through solid blocks }else if(other.solid() && !other.synthetic()){ //skip damage propagation through solid blocks

View File

@@ -723,7 +723,7 @@ public class Mods implements Loadable{
if(!metaf.exists()){ if(!metaf.exists()){
Log.warn("Mod @ doesn't have a '[mod/plugin].[h]json' file, skipping.", sourceFile); Log.warn("Mod @ doesn't have a '[mod/plugin].[h]json' file, skipping.", sourceFile);
throw new IllegalArgumentException("Invalid file: No mod.json found."); throw new ModLoadException("Invalid file: No mod.json found.");
} }
ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain)); ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain));
@@ -750,7 +750,7 @@ public class Mods implements Loadable{
//unload //unload
mods.remove(other); mods.remove(other);
}else{ }else{
throw new IllegalArgumentException("A mod with the name '" + baseName + "' is already imported."); throw new ModLoadException("A mod with the name '" + baseName + "' is already imported.");
} }
} }
@@ -779,12 +779,23 @@ public class Mods implements Loadable{
(meta.getMinMajor() >= 105 || headless) (meta.getMinMajor() >= 105 || headless)
){ ){
if(ios){ if(ios){
throw new IllegalArgumentException("Java class mods are not supported on iOS."); throw new ModLoadException("Java class mods are not supported on iOS.");
} }
loader = platform.loadJar(sourceFile, mainLoader); loader = platform.loadJar(sourceFile, mainLoader);
mainLoader.addChild(loader); mainLoader.addChild(loader);
Class<?> main = Class.forName(mainClass, true, loader); Class<?> main = Class.forName(mainClass, true, loader);
//detect mods that incorrectly package mindustry in the jar
if((main.getSuperclass().getName().equals("mindustry.mod.Plugin") || main.getSuperclass().getName().equals("mindustry.mod.Mod")) &&
main.getSuperclass().getClassLoader() != Mod.class.getClassLoader()){
throw new ModLoadException(
"This mod/plugin has loaded Mindustry dependencies from its own class loader. " +
"You are incorrectly including Mindustry dependencies in the mod JAR - " +
"make sure Mindustry is declared as `compileOnly` in Gradle, and that the JAR is created with `runtimeClasspath`!"
);
}
metas.put(main, meta); metas.put(main, meta);
mainMod = (Mod)main.getDeclaredConstructor().newInstance(); mainMod = (Mod)main.getDeclaredConstructor().newInstance();
}else{ }else{
@@ -1017,6 +1028,12 @@ public class Mods implements Loadable{
} }
} }
public static class ModLoadException extends RuntimeException{
public ModLoadException(String message){
super(message);
}
}
public enum ModState{ public enum ModState{
enabled, enabled,
contentErrors, contentErrors,

View File

@@ -6,19 +6,14 @@ import arc.func.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import arc.util.io.*; import arc.util.io.*;
import arc.util.serialization.*;
import arc.util.serialization.JsonValue.*;
import arc.util.serialization.JsonWriter.*;
import mindustry.*; import mindustry.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.gen.*;
import java.io.*; import java.io.*;
import java.text.*; import java.text.*;
import java.util.*; import java.util.*;
import static arc.Core.*; import static arc.Core.*;
import static mindustry.Vars.net;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class CrashSender{ public class CrashSender{
@@ -126,6 +121,9 @@ public class CrashSender{
}catch(Throwable ignored){ }catch(Throwable ignored){
} }
//disabled until further notice.
/*
JsonValue value = new JsonValue(ValueType.object); JsonValue value = new JsonValue(ValueType.object);
boolean fn = netActive, fs = netServer; boolean fn = netActive, fs = netServer;
@@ -154,7 +152,7 @@ public class CrashSender{
}).block(r -> { }).block(r -> {
Log.info("Crash sent successfully."); Log.info("Crash sent successfully.");
System.exit(1); System.exit(1);
}); });*/
ret(); ret();
}catch(Throwable death){ }catch(Throwable death){

View File

@@ -11,6 +11,7 @@ import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.game.Saves.*; import mindustry.game.Saves.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.g3d.PlanetGrid.*; import mindustry.graphics.g3d.PlanetGrid.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.modules.*; import mindustry.world.modules.*;
@@ -126,6 +127,13 @@ public class Sector{
return info.contentIcon != null ? info.contentIcon.uiIcon : info.icon == null ? null : Fonts.getLargeIcon(info.icon); return info.contentIcon != null ? info.contentIcon.uiIcon : info.icon == null ? null : Fonts.getLargeIcon(info.icon);
} }
@Nullable
public String iconChar(){
if(info.contentIcon != null) return info.contentIcon.emoji();
if(info.icon != null) return Iconc.codes.get(info.icon) + "";
return null;
}
public boolean isCaptured(){ public boolean isCaptured(){
return save != null && !info.waves; return save != null && !info.waves;
} }

View File

@@ -68,6 +68,10 @@ public class Bar extends Element{
return this; return this;
} }
public void flash(){
blink = 1f;
}
public Bar blink(Color color){ public Bar blink(Color color){
blinkColor.set(color); blinkColor.set(color);
return this; return this;
@@ -107,8 +111,10 @@ public class Bar extends Element{
} }
Draw.colorl(0.1f); Draw.colorl(0.1f);
Draw.alpha(parentAlpha);
bar.draw(x, y, width, height); bar.draw(x, y, width, height);
Draw.color(color, blinkColor, blink); Draw.color(color, blinkColor, blink);
Draw.alpha(parentAlpha);
Drawable top = Tex.barTop; Drawable top = Tex.barTop;
float topWidth = width * value; float topWidth = width * value;
@@ -128,7 +134,7 @@ public class Bar extends Element{
GlyphLayout lay = Pools.obtain(GlyphLayout.class, GlyphLayout::new); GlyphLayout lay = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
lay.setText(font, name); lay.setText(font, name);
font.setColor(Color.white); font.setColor(1f, 1f, 1f, parentAlpha);
font.draw(name, x + width / 2f - lay.width / 2f, y + height / 2f + lay.height / 2f + 1); font.draw(name, x + width / 2f - lay.width / 2f, y + height / 2f + lay.height / 2f + 1);
Pools.free(lay); Pools.free(lay);

View File

@@ -21,6 +21,7 @@ import arc.util.*;
import mindustry.*; import mindustry.*;
import mindustry.core.*; import mindustry.core.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import java.util.*; import java.util.*;
@@ -155,6 +156,12 @@ public class Fonts{
} }
} }
}); });
for(Team team : Team.baseTeams){
if(Core.atlas.has("team-" + team.name)){
team.emoji = stringIcons.get(team.name, "");
}
}
} }
/** Called from a static context for use in the loading screen.*/ /** Called from a static context for use in the loading screen.*/

View File

@@ -36,6 +36,7 @@ import static mindustry.Vars.*;
public class ModsDialog extends BaseDialog{ public class ModsDialog extends BaseDialog{
private ObjectMap<String, TextureRegion> textureCache = new ObjectMap<>(); private ObjectMap<String, TextureRegion> textureCache = new ObjectMap<>();
private float modImportProgress;
private String searchtxt = ""; private String searchtxt = "";
private @Nullable Seq<ModListing> modList; private @Nullable Seq<ModListing> modList;
private boolean orderDate = false; private boolean orderDate = false;
@@ -488,11 +489,16 @@ public class ModsDialog extends BaseDialog{
private void handleMod(String repo, HttpResponse result){ private void handleMod(String repo, HttpResponse result){
try{ try{
Fi file = tmpDirectory.child(repo.replace("/", "") + ".zip"); Fi file = tmpDirectory.child(repo.replace("/", "") + ".zip");
Streams.copy(result.getResultAsStream(), file.write(false)); long len = result.getContentLength();
Floatc cons = len <= 0 ? f -> {} : p -> modImportProgress = p;
Streams.copyProgress(result.getResultAsStream(), file.write(false), len, 4096, cons);
var mod = mods.importMod(file); var mod = mods.importMod(file);
mod.setRepo(repo); mod.setRepo(repo);
file.delete(); file.delete();
Core.app.post(() -> { Core.app.post(() -> {
try{ try{
setup(); setup();
ui.loadfrag.hide(); ui.loadfrag.hide();
@@ -510,10 +516,13 @@ public class ModsDialog extends BaseDialog{
} }
private void githubImportMod(String repo, boolean isJava){ private void githubImportMod(String repo, boolean isJava){
modImportProgress = 0f;
ui.loadfrag.show("@downloading");
ui.loadfrag.setProgress(() -> modImportProgress);
if(isJava){ if(isJava){
githubImportJavaMod(repo); githubImportJavaMod(repo);
}else{ }else{
ui.loadfrag.show();
Http.get(ghApi + "/repos/" + repo, res -> { Http.get(ghApi + "/repos/" + repo, res -> {
var json = Jval.read(res.getResultAsString()); var json = Jval.read(res.getResultAsString());
String mainBranch = json.getString("default_branch"); String mainBranch = json.getString("default_branch");

View File

@@ -371,6 +371,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
} }
if(selectAlpha > 0.001f){ if(selectAlpha > 0.001f){
for(Sector sec : planet.sectors){ for(Sector sec : planet.sectors){
if(sec.hasBase()){ if(sec.hasBase()){
for(Sector enemy : sec.near()){ for(Sector enemy : sec.near()){
@@ -378,6 +380,18 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
planets.drawArc(planet, enemy.tile.v, sec.tile.v, Team.crux.color.write(Tmp.c2).a(selectAlpha), Color.clear, 0.24f, 110f, 25); planets.drawArc(planet, enemy.tile.v, sec.tile.v, Team.crux.color.write(Tmp.c2).a(selectAlpha), Color.clear, 0.24f, 110f, 25);
} }
} }
if(selected != null && selected != sec && selected.hasBase()){
//imports
if(sec.info.getRealDestination() == selected && sec.info.anyExports()){
planets.drawArc(planet, sec.tile.v, selected.tile.v, Color.gray.write(Tmp.c2).a(selectAlpha), Pal.accent, 0.4f, 90f, 25);
}
//exports
if(selected.info.getRealDestination() == sec && selected.info.anyExports()){
planets.drawArc(planet, selected.tile.v, sec.tile.v, Pal.place.write(Tmp.c2).a(selectAlpha), Pal.accent, 0.4f, 90f, 25);
}
}
} }
} }
} }
@@ -605,6 +619,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
} }
void displayItems(Table c, float scl, ObjectMap<Item, ExportStat> stats, String name){ void displayItems(Table c, float scl, ObjectMap<Item, ExportStat> stats, String name){
displayItems(c, scl, stats, name, t -> {});
}
void displayItems(Table c, float scl, ObjectMap<Item, ExportStat> stats, String name, Cons<Table> builder){
Table t = new Table().left(); Table t = new Table().left();
int i = 0; int i = 0;
@@ -622,8 +640,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
} }
if(t.getChildren().any()){ if(t.getChildren().any()){
c.add(name).left().row(); c.defaults().left();
c.add(t).padLeft(10f).left().row(); c.add(name).row();
builder.get(c);
c.add(t).padLeft(10f).row();
} }
} }
@@ -633,6 +653,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
dialog.cont.pane(c -> { dialog.cont.pane(c -> {
c.defaults().padBottom(5); c.defaults().padBottom(5);
if(sector.preset != null && sector.preset.description != null){
c.add(sector.preset.displayDescription()).left().row();
}
c.add(Core.bundle.get("sectors.time") + " [accent]" + sector.save.getPlayTime()).left().row(); c.add(Core.bundle.get("sectors.time") + " [accent]" + sector.save.getPlayTime()).left().row();
if(sector.info.waves && sector.hasBase()){ if(sector.info.waves && sector.hasBase()){
@@ -656,11 +680,21 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
displayItems(c, sector.getProductionScale(), sector.info.production, "@sectors.production"); displayItems(c, sector.getProductionScale(), sector.info.production, "@sectors.production");
//export //export
displayItems(c, sector.getProductionScale(), sector.info.export, "@sectors.export"); displayItems(c, sector.getProductionScale(), sector.info.export, "@sectors.export", t -> {
if(sector.info.destination != null){
String ic = sector.info.destination.iconChar();
t.add(Iconc.rightOpen + " " + (ic == null || ic.isEmpty() ? "" : ic + " ") + sector.info.destination.name()).padLeft(10f).row();
}
});
//import //import
if(sector.hasBase()){ if(sector.hasBase()){
displayItems(c, 1f, sector.info.importStats(), "@sectors.import"); displayItems(c, 1f, sector.info.importStats(sector.planet), "@sectors.import", t -> {
sector.info.eachImport(sector.planet, other -> {
String ic = other.iconChar();
t.add(Iconc.rightOpen + " " + (ic == null || ic.isEmpty() ? "" : ic + " ") + other.name()).padLeft(10f).row();
});
});
} }
ItemSeq items = sector.items(); ItemSeq items = sector.items();
@@ -735,10 +769,11 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
t.button(Icon.none, Styles.clearTogglei, () -> { t.button(Icon.none, Styles.clearTogglei, () -> {
sector.info.icon = null; sector.info.icon = null;
sector.info.contentIcon = null;
sector.saveInfo(); sector.saveInfo();
hide(); hide();
updateSelected(); updateSelected();
}).checked(sector.info.icon == null); }).checked(sector.info.icon == null && sector.info.contentIcon == null);
int cols = (int)Math.min(20, Core.graphics.getWidth() / Scl.scl(52f)); int cols = (int)Math.min(20, Core.graphics.getWidth() / Scl.scl(52f));
@@ -746,7 +781,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
for(var key : defaultIcons){ for(var key : defaultIcons){
var value = Icon.icons.get(key); var value = Icon.icons.get(key);
t.button(value, Styles.cleari, () -> { t.button(value, Styles.clearTogglei, () -> {
sector.info.icon = key; sector.info.icon = key;
sector.info.contentIcon = null; sector.info.contentIcon = null;
sector.saveInfo(); sector.saveInfo();
@@ -765,7 +800,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
i = 0; i = 0;
for(UnlockableContent u : content.getBy(ctype).<UnlockableContent>as()){ for(UnlockableContent u : content.getBy(ctype).<UnlockableContent>as()){
if(!u.isHidden() && u.unlocked()){ if(!u.isHidden() && u.unlocked()){
t.button(new TextureRegionDrawable(u.uiIcon), Styles.cleari, iconMed, () -> { t.button(new TextureRegionDrawable(u.uiIcon), Styles.clearTogglei, iconMed, () -> {
sector.info.icon = null; sector.info.icon = null;
sector.info.contentIcon = u; sector.info.contentIcon = u;
sector.saveInfo(); sector.saveInfo();

View File

@@ -369,6 +369,12 @@ public class SettingsMenuDialog extends Dialog{
if(!mobile){ if(!mobile){
graphics.checkPref("vsync", true, b -> Core.graphics.setVSync(b)); graphics.checkPref("vsync", true, b -> Core.graphics.setVSync(b));
graphics.checkPref("fullscreen", false, b -> { graphics.checkPref("fullscreen", false, b -> {
if(b && settings.getBool("borderlesswindow")){
Core.graphics.setWindowedMode(Core.graphics.getWidth(), Core.graphics.getHeight());
settings.put("borderlesswindow", false);
graphics.rebuild();
}
if(b){ if(b){
Core.graphics.setFullscreenMode(Core.graphics.getDisplayMode()); Core.graphics.setFullscreenMode(Core.graphics.getDisplayMode());
}else{ }else{
@@ -376,15 +382,23 @@ public class SettingsMenuDialog extends Dialog{
} }
}); });
graphics.checkPref("borderlesswindow", false, b -> Core.graphics.setUndecorated(b)); graphics.checkPref("borderlesswindow", false, b -> {
if(b && settings.getBool("fullscreen")){
Core.graphics.setWindowedMode(Core.graphics.getWidth(), Core.graphics.getHeight());
settings.put("fullscreen", false);
graphics.rebuild();
}
Core.graphics.setBorderless(b);
});
Core.graphics.setVSync(Core.settings.getBool("vsync")); Core.graphics.setVSync(Core.settings.getBool("vsync"));
if(Core.settings.getBool("fullscreen")){ if(Core.settings.getBool("fullscreen")){
Core.app.post(() -> Core.graphics.setFullscreenMode(Core.graphics.getDisplayMode())); Core.app.post(() -> Core.graphics.setFullscreenMode(Core.graphics.getDisplayMode()));
} }
if(Core.settings.getBool("borderlesswindow")){ if(Core.settings.getBool("borderlesswindow")){
Core.app.post(() -> Core.graphics.setUndecorated(true)); Core.app.post(() -> Core.graphics.setBorderless(true));
} }
}else if(!ios){ }else if(!ios){
graphics.checkPref("landscape", false, b -> { graphics.checkPref("landscape", false, b -> {
@@ -612,7 +626,8 @@ public class SettingsMenuDialog extends Dialog{
Setting(String name){ Setting(String name){
this.name = name; this.name = name;
title = bundle.get("setting." + name + ".name"); String winkey = "setting." + name + ".name.windows";
title = OS.isWindows && bundle.has(winkey) ? bundle.get(winkey) : bundle.get("setting." + name + ".name");
description = bundle.getOrNull("setting." + name + ".description"); description = bundle.getOrNull("setting." + name + ".description");
} }

View File

@@ -32,7 +32,7 @@ public class ChatFragment extends Table{
private Font font; private Font font;
private GlyphLayout layout = new GlyphLayout(); private GlyphLayout layout = new GlyphLayout();
private float offsetx = Scl.scl(4), offsety = Scl.scl(4), fontoffsetx = Scl.scl(2), chatspace = Scl.scl(50); private float offsetx = Scl.scl(4), offsety = Scl.scl(4), fontoffsetx = Scl.scl(2), chatspace = Scl.scl(50);
private Color shadowColor = new Color(0, 0, 0, 0.4f); private Color shadowColor = new Color(0, 0, 0, 0.5f);
private float textspacing = Scl.scl(10); private float textspacing = Scl.scl(10);
private Seq<String> history = new Seq<>(); private Seq<String> history = new Seq<>();
private int historyPos = 0; private int historyPos = 0;

View File

@@ -38,7 +38,7 @@ public class LoadingFragment extends Fragment{
text("@loading"); text("@loading");
bar = t.add(new Bar()).pad(3).size(500f, 40f).visible(false).get(); bar = t.add(new Bar()).pad(3).padTop(6).size(500f, 40f).visible(false).get();
t.row(); t.row();
button = t.button("@cancel", () -> {}).pad(20).size(250f, 70f).visible(false).get(); button = t.button("@cancel", () -> {}).pad(20).size(250f, 70f).visible(false).get();
table = t; table = t;

View File

@@ -15,6 +15,7 @@ import mindustry.core.*;
import mindustry.entities.*; import mindustry.entities.*;
import mindustry.entities.units.*; import mindustry.entities.units.*;
import mindustry.game.EventType.*; import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.graphics.*; import mindustry.graphics.*;
import mindustry.input.*; import mindustry.input.*;
@@ -38,6 +39,7 @@ public class PlacementFragment extends Fragment{
Block menuHoverBlock; Block menuHoverBlock;
Displayable hover; Displayable hover;
Object lastDisplayState; Object lastDisplayState;
Team lastTeam;
boolean wasHovered; boolean wasHovered;
Table blockTable, toggler, topTable; Table blockTable, toggler, topTable;
ScrollPane blockPane; ScrollPane blockPane;
@@ -283,13 +285,14 @@ public class PlacementFragment extends Fragment{
//don't refresh unnecessarily //don't refresh unnecessarily
//refresh only when the hover state changes, or the displayed block changes //refresh only when the hover state changes, or the displayed block changes
if(wasHovered == isHovered && lastDisplayState == displayState) return; if(wasHovered == isHovered && lastDisplayState == displayState && lastTeam == player.team()) return;
topTable.clear(); topTable.clear();
topTable.top().left().margin(5); topTable.top().left().margin(5);
lastDisplayState = displayState; lastDisplayState = displayState;
wasHovered = isHovered; wasHovered = isHovered;
lastTeam = player.team();
//show details of selected block, with costs //show details of selected block, with costs
if(displayBlock != null){ if(displayBlock != null){

View File

@@ -886,6 +886,36 @@ public class Block extends UnlockableContent{
} }
} }
//generate paletted team regions
if(teamRegion.found()){
for(Team team : Team.all){
//if there's an override, don't generate anything
if(team.hasPalette && !Core.atlas.has(name + "-team-" + team.name)){
var base = Core.atlas.getPixmap(teamRegion);
Pixmap out = new Pixmap(base.width, base.height);
for(int x = 0; x < base.width; x++){
for(int y = 0; y < base.height; y++){
int color = base.get(x, y);
int index = color == 0xffffffff ? 0 : color == 0xdcc6c6ff ? 1 : color == 0x9d7f7fff ? 2 : -1;
out.setRaw(x, y, index == -1 ? base.get(x, y) : team.palettei[index]);
}
}
if(Core.settings.getBool("linear")){
Pixmaps.bleed(out);
}
packer.add(PageType.main, name + "-team-" + team.name, out);
}
}
teamRegions = new TextureRegion[Team.all.length];
for(Team team : Team.all){
teamRegions[team.id] = teamRegion.found() && team.hasPalette ? Core.atlas.find(name + "-team-" + team.name, teamRegion) : teamRegion;
}
}
Pixmap last = null; Pixmap last = null;
var gen = icons(); var gen = icons();

View File

@@ -108,7 +108,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
} }
/** /**
* Returns the flammability of the Used for fire calculations. * Returns the flammability of the tile. Used for fire calculations.
* Takes flammability of floor liquid into account. * Takes flammability of floor liquid into account.
*/ */
public float getFlammability(){ public float getFlammability(){
@@ -675,7 +675,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
build.health = health; build.health = health;
if(build.damaged()){ if(build.damaged()){
indexer.notifyTileDamaged(build); indexer.notifyBuildDamaged(build);
} }
} }

View File

@@ -84,6 +84,11 @@ public class ConstructBlock extends Block{
if(builder != null && builder.getControllerName() != null){ if(builder != null && builder.getControllerName() != null){
tile.build.lastAccessed = builder.getControllerName(); tile.build.lastAccessed = builder.getControllerName();
} }
//make sure block indexer knows it's damaged
if(tile.build.damaged()){
indexer.notifyBuildDamaged(tile.build);
}
} }
//last builder was this local client player, call placed() //last builder was this local client player, call placed()

View File

@@ -21,7 +21,6 @@ import mindustry.logic.*;
import mindustry.type.*; import mindustry.type.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.world.blocks.payloads.*; import mindustry.world.blocks.payloads.*;
import mindustry.world.consumers.*;
import mindustry.world.meta.*; import mindustry.world.meta.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
@@ -61,12 +60,6 @@ public class PayloadLaunchPad extends PayloadBlock{
return !state.isCampaign() || net.client() ? SystemCursor.arrow : super.getCursor(); return !state.isCampaign() || net.client() ? SystemCursor.arrow : super.getCursor();
} }
//cannot be disabled
@Override
public float efficiency(){
return power != null && (block.consumes.has(ConsumeType.power) && !block.consumes.getPower().buffered) ? power.status : 1f;
}
@Override @Override
public boolean shouldConsume(){ public boolean shouldConsume(){
return true; return true;

View File

@@ -178,7 +178,7 @@ public class ItemBridge extends Block{
public int link = -1; public int link = -1;
public IntSeq incoming = new IntSeq(false, 4); public IntSeq incoming = new IntSeq(false, 4);
public float warmup; public float warmup;
public float time; public float time = -8f, timeSpeed;
public boolean wasMoved, moved; public boolean wasMoved, moved;
public float transportCounter; public float transportCounter;
@@ -295,7 +295,10 @@ public class ItemBridge extends Block{
moved = false; moved = false;
} }
time += wasMoved ? delta() : 0f; //smooth out animation, so it doesn't stop/start immediately
timeSpeed = Mathf.approachDelta(timeSpeed, wasMoved ? 1f : 0f, 1f / 60f);
time += timeSpeed * delta();
checkIncoming(); checkIncoming();
@@ -352,6 +355,8 @@ public class ItemBridge extends Block{
Draw.color(Color.white, Color.black, Mathf.absin(Time.time, 6f, 0.07f)); Draw.color(Color.white, Color.black, Mathf.absin(Time.time, 6f, 0.07f));
} }
float warmup = hasPower ? this.warmup : 1f;
Draw.alpha((fadeIn ? Math.max(warmup, 0.25f) : 1f) * Renderer.bridgeOpacity); Draw.alpha((fadeIn ? Math.max(warmup, 0.25f) : 1f) * Renderer.bridgeOpacity);
Draw.rect(endRegion, x, y, i * 90 + 90); Draw.rect(endRegion, x, y, i * 90 + 90);

View File

@@ -28,7 +28,7 @@ public class Floor extends Block{
public float dragMultiplier = 1f; public float dragMultiplier = 1f;
/** Damage taken per tick on this tile. */ /** Damage taken per tick on this tile. */
public float damageTaken = 0f; public float damageTaken = 0f;
/** How many ticks it takes to drown on this. */ /** How many ticks it takes to drown on this. 0 to disable. */
public float drownTime = 0f; public float drownTime = 0f;
/** Effect when walking on this floor. */ /** Effect when walking on this floor. */
public Effect walkEffect = Fx.none; public Effect walkEffect = Fx.none;
@@ -42,11 +42,11 @@ public class Floor extends Block{
public StatusEffect status = StatusEffects.none; public StatusEffect status = StatusEffects.none;
/** Intensity of applied status effect. */ /** Intensity of applied status effect. */
public float statusDuration = 60f; public float statusDuration = 60f;
/** liquids that drop from this block, used for pumps */ /** liquids that drop from this block, used for pumps. */
public @Nullable Liquid liquidDrop = null; public @Nullable Liquid liquidDrop = null;
/** Multiplier for pumped liquids, used for deep water. */ /** Multiplier for pumped liquids, used for deep water. */
public float liquidMultiplier = 1f; public float liquidMultiplier = 1f;
/** whether this block can be drowned in */ /** whether this block is liquid. */
public boolean isLiquid; public boolean isLiquid;
/** if true, this block cannot be mined by players. useful for annoying things like sand. */ /** if true, this block cannot be mined by players. useful for annoying things like sand. */
public boolean playerUnmineable = false; public boolean playerUnmineable = false;

View File

@@ -174,7 +174,7 @@ public class LogicBlock extends Block{
public boolean active = true, valid; public boolean active = true, valid;
public int x, y; public int x, y;
public String name; public String name;
Building lastBuild; public Building lastBuild;
public LogicLink(int x, int y, String name, boolean valid){ public LogicLink(int x, int y, String name, boolean valid){
this.x = x; this.x = x;
@@ -397,7 +397,8 @@ public class LogicBlock extends Block{
var cur = world.build(l.x, l.y); var cur = world.build(l.x, l.y);
boolean valid = validLink(cur); boolean valid = validLink(cur);
if(valid != l.valid || (l.lastBuild != null && l.lastBuild != cur)){ if(l.lastBuild == null) l.lastBuild = cur;
if(valid != l.valid || l.lastBuild != cur){
l.lastBuild = cur; l.lastBuild = cur;
changed = true; changed = true;
l.valid = valid; l.valid = valid;

View File

@@ -106,6 +106,15 @@ public class LogicDisplay extends Block{
}); });
Draw.blend(); Draw.blend();
} }
@Override
public void remove(){
super.remove();
if(buffer != null){
buffer.dispose();
buffer = null;
}
}
} }
static int unpackSign(int value){ static int unpackSign(int value){

View File

@@ -193,8 +193,14 @@ public class PayloadBlock extends Block{
} }
public void dumpPayload(){ public void dumpPayload(){
//translate payload forward slightly
float tx = Angles.trnsx(payload.rotation(), 0.1f), ty = Angles.trnsy(payload.rotation(), 0.1f);
payload.set(payload.x() + tx, payload.y() + ty, payload.rotation());
if(payload.dump()){ if(payload.dump()){
payload = null; payload = null;
}else{
payload.set(payload.x() - tx, payload.y() - ty, payload.rotation());
} }
} }

View File

@@ -363,6 +363,7 @@ public class PowerNode extends PowerBlock{
@Override @Override
public void dropped(){ public void dropped(){
power.links.clear(); power.links.clear();
updatePowerGraph();
} }
@Override @Override

View File

@@ -29,8 +29,8 @@ public class CoreBlock extends StorageBlock{
//hacky way to pass item modules between methods //hacky way to pass item modules between methods
private static ItemModule nextItems; private static ItemModule nextItems;
public @Load("@-thruster1") TextureRegion thruster1; //top right public @Load(value = "@-thruster1", fallback = "clear-effect") TextureRegion thruster1; //top right
public @Load("@-thruster2") TextureRegion thruster2; //bot left public @Load(value = "@-thruster2", fallback = "clear-effect") TextureRegion thruster2; //bot left
public float thrusterLength = 14f/4f; public float thrusterLength = 14f/4f;
public UnitType unitType = UnitTypes.alpha; public UnitType unitType = UnitTypes.alpha;

View File

@@ -41,7 +41,7 @@ public class StorageBlock extends Block{
} }
public class StorageBuild extends Building{ public class StorageBuild extends Building{
protected @Nullable Building linkedCore; public @Nullable Building linkedCore;
@Override @Override
public boolean acceptItem(Building source, Item item){ public boolean acceptItem(Building source, Item item){

View File

@@ -126,6 +126,7 @@ platforms.each{ platform ->
} }
args += "Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1" args += "Dhttps.protocols=TLSv1.2,TLSv1.1,TLSv1"
args += "XX:+ShowCodeDetailsInExceptionMessages"
exec{ exec{
commandLine args.toList() commandLine args.toList()

View File

@@ -100,9 +100,6 @@ public class DesktopLauncher extends ClientLauncher{
if(SteamAPI.restartAppIfNecessary(SVars.steamID)){ if(SteamAPI.restartAppIfNecessary(SVars.steamID)){
System.exit(0); System.exit(0);
} }
}catch(NullPointerException ignored){
steam = false;
Log.info("Running in offline mode.");
}catch(Throwable e){ }catch(Throwable e){
steam = false; steam = false;
Log.err("Failed to load Steam native libraries."); Log.err("Failed to load Steam native libraries.");

View File

@@ -33,10 +33,9 @@ public class SWorkshop implements SteamUGCCallback{
ItemInstallInfo info = new ItemInstallInfo(); ItemInstallInfo info = new ItemInstallInfo();
ugc.getSubscribedItems(ids); ugc.getSubscribedItems(ids);
Seq<Fi> folders = Seq.with(ids).map(f -> { Seq<Fi> folders = Seq.with(ids)
ugc.getItemInstallInfo(f, info); .map(f -> !ugc.getItemInstallInfo(f, info) || info.getFolder() == null ? null : new Fi(info.getFolder()))
return new Fi(info.getFolder()); .select(f -> f != null && f.list().length > 0);
}).select(f -> f != null && f.list().length > 0);
workshopFiles.put(Map.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(mapExtension)).map(f -> f.list()[0])); workshopFiles.put(Map.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(mapExtension)).map(f -> f.list()[0]));
workshopFiles.put(Schematic.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(schematicExtension)).map(f -> f.list()[0])); workshopFiles.put(Schematic.class, folders.select(f -> f.list().length == 1 && f.list()[0].extension().equals(schematicExtension)).map(f -> f.list()[0]));

View File

@@ -1,7 +1,5 @@
org.gradle.daemon=true org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m --illegal-access=permit org.gradle.jvmargs=-Xms256m -Xmx1024m --illegal-access=permit
# Don't recompute annotations if sources haven't been changed
kapt.incremental.apt = true
# Multithreaded # Multithreaded
kapt.use.worker.api=true kapt.use.worker.api=true
# Compilation avoidance (see https://kotlinlang.org/docs/kapt.html#compile-avoidance-for-kapt-since-1-3-20) # Compilation avoidance (see https://kotlinlang.org/docs/kapt.html#compile-avoidance-for-kapt-since-1-3-20)
@@ -10,4 +8,4 @@ kapt.include.compile.classpath=false
kotlin.stdlib.default.dependency=false kotlin.stdlib.default.dependency=false
#needed for android compilation #needed for android compilation
android.useAndroidX=true android.useAndroidX=true
archash=a9dedf9345fe888e54ab2be3c56bf8d4d2aeb2b8 archash=4bd83c8f1cf35670e48418b6fa2297400895a1c4

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -380,6 +380,8 @@ public class ServerControl implements ApplicationListener{
maps.reload(); maps.reload();
if(maps.all().size > beforeMaps){ if(maps.all().size > beforeMaps){
info("@ new map(s) found and reloaded.", maps.all().size - beforeMaps); info("@ new map(s) found and reloaded.", maps.all().size - beforeMaps);
}else if(maps.all().size < beforeMaps){
info("@ old map(s) deleted.", beforeMaps - maps.all().size);
}else{ }else{
info("Maps reloaded."); info("Maps reloaded.");
} }

View File

@@ -57,7 +57,7 @@
}, },
{ {
"name": "Omega", "name": "Omega",
"address": ["178.170.47.34:20204", "157.90.213.2:30308", "157.90.180.53:25738", "185.86.230.61:25578"] "address": ["178.170.47.34:20204", "157.90.213.2:30308", "157.90.180.53:25738", "185.86.230.61:25578", "mindustry.me:7172"]
}, },
{ {
"name": "md.obvilionnetwork.ru", "name": "md.obvilionnetwork.ru",
@@ -77,7 +77,7 @@
}, },
{ {
"name": "TSR", "name": "TSR",
"address": ["de15-3.falix.gg:27422"] "address": ["ult4.falix.gg:26904"]
}, },
{ {
"name": "Sakura", "name": "Sakura",

View File

@@ -154,7 +154,7 @@ public class FakeGraphics extends Graphics{
} }
@Override @Override
public void setUndecorated(boolean undecorated){ public void setBorderless(boolean undecorated){
} }

View File

@@ -244,7 +244,7 @@ public class Generators{
teamr.each((x, y) -> { teamr.each((x, y) -> {
int color = teamr.getRaw(x, y); int color = teamr.getRaw(x, y);
int index = color == 0xffffffff ? 0 : color == 0xdcc6c6ff ? 1 : color == 0x9d7f7fff ? 2 : -1; int index = color == 0xffffffff ? 0 : color == 0xdcc6c6ff ? 1 : color == 0x9d7f7fff ? 2 : -1;
out.setRaw(x, y, index == -1 ? teamr.getRaw(x, y) : team.palette[index].rgba()); out.setRaw(x, y, index == -1 ? teamr.getRaw(x, y) : team.palettei[index]);
}); });
save(out, block.name + "-team-" + team.name); save(out, block.name + "-team-" + team.name);
@@ -390,6 +390,19 @@ public class Generators{
} }
}); });
generate("team-icons", () -> {
for(Team team : Team.all){
if(has("team-" + team.name)){
int rgba = team == Team.derelict ? Color.valueOf("b7b8c9").rgba() : team.color.rgba();
Pixmap base = get("team-" + team.name);
base.each((x, y) -> base.setRaw(x, y, Color.muli(base.getRaw(x, y), rgba)));
delete("team-" + team.name);
save(base.outline(Pal.gray, 3), "../ui/team-" + team.name);
}
}
});
generate("unit-icons", () -> content.units().each(type -> { generate("unit-icons", () -> content.units().each(type -> {
if(type.isHidden()) return; //hidden units don't generate if(type.isHidden()) return; //hidden units don't generate

View File

@@ -236,6 +236,10 @@ public class ImagePacker{
base.draw(image, 0, 0, image.width, image.height, base.width/2 - wx/2, base.height/2 - wy/2, wx, wy, true, true); base.draw(image, 0, 0, image.width, image.height, base.width/2 - wx/2, base.height/2 - wy/2, wx, wy, true, true);
} }
static void delete(String name){
((GenRegion)Core.atlas.find(name)).path.delete();
}
static void replace(String name, Pixmap image){ static void replace(String name, Pixmap image){
Fi.get(name + ".png").writePng(image); Fi.get(name + ".png").writePng(image);
((GenRegion)Core.atlas.find(name)).path.delete(); ((GenRegion)Core.atlas.find(name)).path.delete();