diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 97d7e72411..f78bf1406b 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -502,6 +502,7 @@ wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Details... edit = Edit diff --git a/core/assets/bundles/bundle_be.properties b/core/assets/bundles/bundle_be.properties index 96dcc89d10..ed06804542 100644 --- a/core/assets/bundles/bundle_be.properties +++ b/core/assets/bundles/bundle_be.properties @@ -489,6 +489,7 @@ waves.units.show = Паказаць Усё wavemode.counts = колькацсь адзінак wavemode.totals = усяго здароўя wavemode.health = здароўе +all = All editor.default = [lightgray]<Па змаўчанні> details = Падрабязнасці... diff --git a/core/assets/bundles/bundle_bg.properties b/core/assets/bundles/bundle_bg.properties index e26ee0698b..b3ad23c548 100644 --- a/core/assets/bundles/bundle_bg.properties +++ b/core/assets/bundles/bundle_bg.properties @@ -495,6 +495,7 @@ waves.units.show = Show All wavemode.counts = бройки wavemode.totals = общи бройки wavemode.health = точки живот +all = All editor.default = [lightgray]<Стандартно> details = Детайли... diff --git a/core/assets/bundles/bundle_ca.properties b/core/assets/bundles/bundle_ca.properties index b376c31b82..dd1a5c6546 100644 --- a/core/assets/bundles/bundle_ca.properties +++ b/core/assets/bundles/bundle_ca.properties @@ -495,6 +495,7 @@ waves.units.show = Mostra-les totes wavemode.counts = comptades wavemode.totals = totals wavemode.health = salut +all = All editor.default = [lightgray] details = Detalls diff --git a/core/assets/bundles/bundle_cs.properties b/core/assets/bundles/bundle_cs.properties index 071f78d584..069eee3479 100644 --- a/core/assets/bundles/bundle_cs.properties +++ b/core/assets/bundles/bundle_cs.properties @@ -496,6 +496,7 @@ waves.units.show = Zobrazit vše wavemode.counts = počty wavemode.totals = součty wavemode.health = zdraví +all = All editor.default = [lightgray][] details = Podrobnosti... diff --git a/core/assets/bundles/bundle_da.properties b/core/assets/bundles/bundle_da.properties index 427f92b696..e54d3b9f00 100644 --- a/core/assets/bundles/bundle_da.properties +++ b/core/assets/bundles/bundle_da.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = tal wavemode.totals = i alt wavemode.health = liv +all = All editor.default = [lightgray] details = Detaljer... diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index 891ba73ec7..bf5e187361 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -498,6 +498,7 @@ waves.units.show = Alle anzeigen wavemode.counts = Menge wavemode.totals = Gesamtmenge wavemode.health = Lebenspunkte +all = All editor.default = [lightgray] details = Details diff --git a/core/assets/bundles/bundle_es.properties b/core/assets/bundles/bundle_es.properties index 86abffb144..dd316e0383 100644 --- a/core/assets/bundles/bundle_es.properties +++ b/core/assets/bundles/bundle_es.properties @@ -495,6 +495,7 @@ waves.units.show = Mostrar todo wavemode.counts = limitadas wavemode.totals = totales wavemode.health = por salud +all = All editor.default = [lightgray] details = Detalles... diff --git a/core/assets/bundles/bundle_et.properties b/core/assets/bundles/bundle_et.properties index 8e73c45c6f..23d5d3de70 100644 --- a/core/assets/bundles/bundle_et.properties +++ b/core/assets/bundles/bundle_et.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Üksikasjad... diff --git a/core/assets/bundles/bundle_eu.properties b/core/assets/bundles/bundle_eu.properties index 86d65b0b6e..a3c3f2a694 100644 --- a/core/assets/bundles/bundle_eu.properties +++ b/core/assets/bundles/bundle_eu.properties @@ -492,6 +492,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Xehetasunak... diff --git a/core/assets/bundles/bundle_fi.properties b/core/assets/bundles/bundle_fi.properties index 083b228f34..83abf0d3a4 100644 --- a/core/assets/bundles/bundle_fi.properties +++ b/core/assets/bundles/bundle_fi.properties @@ -490,6 +490,7 @@ waves.units.show = Näytä kaikki wavemode.counts = lukumäärä wavemode.totals = yhteismäärä wavemode.health = elämäpisteet +all = All editor.default = [lightgray] details = Yksityiskohdat... diff --git a/core/assets/bundles/bundle_fil.properties b/core/assets/bundles/bundle_fil.properties index a46362d3bd..08dd5e1cb5 100644 --- a/core/assets/bundles/bundle_fil.properties +++ b/core/assets/bundles/bundle_fil.properties @@ -490,6 +490,7 @@ waves.units.show = Ipakita lahat wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Details... diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index bf87912183..4b171c7fca 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -501,6 +501,7 @@ waves.units.show = Afficher tout wavemode.counts = compte wavemode.totals = totaux wavemode.health = santé +all = All editor.default = [lightgray] details = Détails... diff --git a/core/assets/bundles/bundle_hu.properties b/core/assets/bundles/bundle_hu.properties index 934dc7ceef..b779362412 100644 --- a/core/assets/bundles/bundle_hu.properties +++ b/core/assets/bundles/bundle_hu.properties @@ -501,6 +501,7 @@ waves.units.show = Összes megjelenítése wavemode.counts = típusokra bontva wavemode.totals = összesítés wavemode.health = életpontok +all = All editor.default = [lightgray] details = Részletek... diff --git a/core/assets/bundles/bundle_id_ID.properties b/core/assets/bundles/bundle_id_ID.properties index 6a04aef2a1..e0f2a925fc 100644 --- a/core/assets/bundles/bundle_id_ID.properties +++ b/core/assets/bundles/bundle_id_ID.properties @@ -501,6 +501,7 @@ waves.units.show = Perlihatkan Semua wavemode.counts = jumlah wavemode.totals = total wavemode.health = darah +all = All editor.default = [lightgray] details = Detail... diff --git a/core/assets/bundles/bundle_it.properties b/core/assets/bundles/bundle_it.properties index 193b474fbb..7daf0b09cd 100644 --- a/core/assets/bundles/bundle_it.properties +++ b/core/assets/bundles/bundle_it.properties @@ -493,6 +493,7 @@ waves.units.show = Mostra tutto wavemode.counts = conteggi wavemode.totals = totali wavemode.health = salute +all = All editor.default = [lightgray] details = Dettagli... diff --git a/core/assets/bundles/bundle_ja.properties b/core/assets/bundles/bundle_ja.properties index 4fe44e98c2..0053e421af 100644 --- a/core/assets/bundles/bundle_ja.properties +++ b/core/assets/bundles/bundle_ja.properties @@ -495,6 +495,7 @@ waves.units.show = すべて表示 wavemode.counts = 数 wavemode.totals = 総数 wavemode.health = 総体力 +all = All editor.default = [lightgray]<デフォルト> details = 詳細... diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 47ab2f186e..24ad30681f 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -494,6 +494,7 @@ waves.units.show = 모두 보이기 wavemode.counts = 기 wavemode.totals = 총 wavemode.health = 체력 +all = All editor.default = [lightgray]<기본값> details = 설명... diff --git a/core/assets/bundles/bundle_lt.properties b/core/assets/bundles/bundle_lt.properties index 9086006d56..f79a675a1a 100644 --- a/core/assets/bundles/bundle_lt.properties +++ b/core/assets/bundles/bundle_lt.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Detaliau... diff --git a/core/assets/bundles/bundle_nl.properties b/core/assets/bundles/bundle_nl.properties index 62ec0c3317..283c7fb129 100644 --- a/core/assets/bundles/bundle_nl.properties +++ b/core/assets/bundles/bundle_nl.properties @@ -498,6 +498,7 @@ waves.units.show = Toon Alle wavemode.counts = telt wavemode.totals = totalen wavemode.health = levenspunten +all = All editor.default = [lightgray] details = Details... diff --git a/core/assets/bundles/bundle_nl_BE.properties b/core/assets/bundles/bundle_nl_BE.properties index c5718e10ba..832f8dbb7e 100644 --- a/core/assets/bundles/bundle_nl_BE.properties +++ b/core/assets/bundles/bundle_nl_BE.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Details... diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index 5600cee5d0..0720a339ea 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -495,6 +495,7 @@ waves.units.show = Pokaż Wszystkie wavemode.counts = liczba wavemode.totals = sumy wavemode.health = życie +all = All editor.default = [lightgray] details = Detale... diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index e56f3c5f4f..fd27e0538c 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -495,6 +495,7 @@ waves.units.show = Mostrar tudo wavemode.counts = quantidade wavemode.totals = total wavemode.health = vida +all = All editor.default = [lightgray] details = Detalhes... diff --git a/core/assets/bundles/bundle_pt_PT.properties b/core/assets/bundles/bundle_pt_PT.properties index 70235d6448..46ad16e2eb 100644 --- a/core/assets/bundles/bundle_pt_PT.properties +++ b/core/assets/bundles/bundle_pt_PT.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Detalhes... diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index d0ba3ca619..b5a11e3cce 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -495,6 +495,7 @@ waves.units.show = Vezi Tot wavemode.counts = numere wavemode.totals = totaluri wavemode.health = viață +all = All editor.default = [lightgray] details = Detalii... diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index 25a942f67f..e0d05c7252 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -495,6 +495,7 @@ waves.units.show = Показать все wavemode.counts = количество единиц wavemode.totals = всего единиц wavemode.health = всего прочности +all = All editor.default = [lightgray]<По умолчанию> details = Подробности… diff --git a/core/assets/bundles/bundle_sr.properties b/core/assets/bundles/bundle_sr.properties index f69083baaa..971cad09e4 100644 --- a/core/assets/bundles/bundle_sr.properties +++ b/core/assets/bundles/bundle_sr.properties @@ -495,6 +495,7 @@ waves.units.show = Pokaži Sve wavemode.counts = količina wavemode.totals = ukupno wavemode.health = snaga +all = All editor.default = [lightgray] details = Detalji... diff --git a/core/assets/bundles/bundle_sv.properties b/core/assets/bundles/bundle_sv.properties index 836b95d5e8..0daa35f28f 100644 --- a/core/assets/bundles/bundle_sv.properties +++ b/core/assets/bundles/bundle_sv.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Details... diff --git a/core/assets/bundles/bundle_th.properties b/core/assets/bundles/bundle_th.properties index f31434de45..ee41ccf953 100644 --- a/core/assets/bundles/bundle_th.properties +++ b/core/assets/bundles/bundle_th.properties @@ -495,6 +495,7 @@ waves.units.show = แสดงทั้งหมด wavemode.counts = จำนวน wavemode.totals = ทั้งหมด wavemode.health = พลังชีวิต +all = All editor.default = [lightgray]<ค่าเริ่มต้น> details = รายละเอียด... diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties index 66c5786774..c8a3ca2173 100644 --- a/core/assets/bundles/bundle_tk.properties +++ b/core/assets/bundles/bundle_tk.properties @@ -490,6 +490,7 @@ waves.units.show = Show All wavemode.counts = counts wavemode.totals = totals wavemode.health = health +all = All editor.default = [lightgray] details = Details... diff --git a/core/assets/bundles/bundle_tr.properties b/core/assets/bundles/bundle_tr.properties index b4c9f219c4..207a7a91a7 100644 --- a/core/assets/bundles/bundle_tr.properties +++ b/core/assets/bundles/bundle_tr.properties @@ -495,6 +495,7 @@ waves.units.show = Hepsini Göster wavemode.counts = miktarlar wavemode.totals = toplamlar wavemode.health = can +all = All editor.default = [lightgray] details = Detaylar... diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties index 5e8ca2e415..d416bcb7be 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -497,6 +497,7 @@ waves.units.show = Показати все wavemode.counts = кількість wavemode.totals = усього wavemode.health = здоров’я +all = All editor.default = [lightgray]<За замовчуванням> details = Подробиці… diff --git a/core/assets/bundles/bundle_vi.properties b/core/assets/bundles/bundle_vi.properties index ec0526feaa..0e04d120f1 100644 --- a/core/assets/bundles/bundle_vi.properties +++ b/core/assets/bundles/bundle_vi.properties @@ -501,6 +501,7 @@ waves.units.show = Hiện tất cả wavemode.counts = số lượng wavemode.totals = tổng số wavemode.health = độ bền +all = All editor.default = [lightgray] details = Chi tiết... diff --git a/core/assets/bundles/bundle_zh_CN.properties b/core/assets/bundles/bundle_zh_CN.properties index 09161c92df..8ac2aebb27 100644 --- a/core/assets/bundles/bundle_zh_CN.properties +++ b/core/assets/bundles/bundle_zh_CN.properties @@ -498,6 +498,7 @@ waves.units.show = 全部显示 wavemode.counts = 数目 wavemode.totals = 总数 wavemode.health = 生命值 +all = All editor.default = [lightgray]<默认> details = 详情… diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 4427209c0f..63d3873294 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -495,6 +495,7 @@ waves.units.show = 全部顯示 wavemode.counts = 數量 wavemode.totals = 總數 wavemode.health = 生命值 +all = All editor.default = [lightgray](預設) details = 詳細資訊…… diff --git a/core/src/mindustry/ClientLauncher.java b/core/src/mindustry/ClientLauncher.java index 2e8d7396c1..c68681b7a9 100644 --- a/core/src/mindustry/ClientLauncher.java +++ b/core/src/mindustry/ClientLauncher.java @@ -62,7 +62,9 @@ public abstract class ClientLauncher extends ApplicationCore implements Platform } long ram = Runtime.getRuntime().maxMemory(); boolean gb = ram >= 1024 * 1024 * 1024; - Log.info("[RAM] Available: @ @", Strings.fixed(gb ? ram / 1024f / 1024 / 1024f : ram / 1024f / 1024f, 1), gb ? "GB" : "MB"); + if(!OS.isIos){ + Log.info("[RAM] Available: @ @", Strings.fixed(gb ? ram / 1024f / 1024 / 1024f : ram / 1024f / 1024f, 1), gb ? "GB" : "MB"); + } Time.setDeltaProvider(() -> { float result = Core.graphics.getDeltaTime() * 60f; diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index dfd856d56a..03c6cf3f2e 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1513,27 +1513,23 @@ public class Blocks{ requirements(Category.defense, with(Items.copper, 6)); health = 80 * wallHealthMultiplier; researchCostMultiplier = 0.1f; - envDisabled |= Env.scorching; }}; copperWallLarge = new Wall("copper-wall-large"){{ requirements(Category.defense, ItemStack.mult(copperWall.requirements, 4)); health = 80 * 4 * wallHealthMultiplier; size = 2; - envDisabled |= Env.scorching; }}; titaniumWall = new Wall("titanium-wall"){{ requirements(Category.defense, with(Items.titanium, 6)); health = 110 * wallHealthMultiplier; - envDisabled |= Env.scorching; }}; titaniumWallLarge = new Wall("titanium-wall-large"){{ requirements(Category.defense, ItemStack.mult(titaniumWall.requirements, 4)); health = 110 * wallHealthMultiplier * 4; size = 2; - envDisabled |= Env.scorching; }}; plastaniumWall = new Wall("plastanium-wall"){{ @@ -1542,7 +1538,6 @@ public class Blocks{ insulated = true; absorbLasers = true; schematicPriority = 10; - envDisabled |= Env.scorching; }}; plastaniumWallLarge = new Wall("plastanium-wall-large"){{ @@ -1552,20 +1547,17 @@ public class Blocks{ insulated = true; absorbLasers = true; schematicPriority = 10; - envDisabled |= Env.scorching; }}; thoriumWall = new Wall("thorium-wall"){{ requirements(Category.defense, with(Items.thorium, 6)); health = 200 * wallHealthMultiplier; - envDisabled |= Env.scorching; }}; thoriumWallLarge = new Wall("thorium-wall-large"){{ requirements(Category.defense, ItemStack.mult(thoriumWall.requirements, 4)); health = 200 * wallHealthMultiplier * 4; size = 2; - envDisabled |= Env.scorching; }}; phaseWall = new Wall("phase-wall"){{ @@ -1573,7 +1565,6 @@ public class Blocks{ health = 150 * wallHealthMultiplier; chanceDeflect = 10f; flashHit = true; - envDisabled |= Env.scorching; }}; phaseWallLarge = new Wall("phase-wall-large"){{ @@ -1582,14 +1573,12 @@ public class Blocks{ size = 2; chanceDeflect = 10f; flashHit = true; - envDisabled |= Env.scorching; }}; surgeWall = new Wall("surge-wall"){{ requirements(Category.defense, with(Items.surgeAlloy, 6)); health = 230 * wallHealthMultiplier; lightningChance = 0.05f; - envDisabled |= Env.scorching; }}; surgeWallLarge = new Wall("surge-wall-large"){{ @@ -1597,13 +1586,11 @@ public class Blocks{ health = 230 * 4 * wallHealthMultiplier; size = 2; lightningChance = 0.05f; - envDisabled |= Env.scorching; }}; door = new Door("door"){{ requirements(Category.defense, with(Items.titanium, 6, Items.silicon, 4)); health = 100 * wallHealthMultiplier; - envDisabled |= Env.scorching; }}; doorLarge = new Door("door-large"){{ @@ -1612,14 +1599,12 @@ public class Blocks{ closefx = Fx.doorcloselarge; health = 100 * 4 * wallHealthMultiplier; size = 2; - envDisabled |= Env.scorching; }}; scrapWall = new Wall("scrap-wall"){{ requirements(Category.defense, BuildVisibility.sandboxOnly, with(Items.scrap, 6)); health = 60 * wallHealthMultiplier; variants = 5; - envDisabled |= Env.scorching; }}; scrapWallLarge = new Wall("scrap-wall-large"){{ @@ -1627,7 +1612,6 @@ public class Blocks{ health = 60 * 4 * wallHealthMultiplier; size = 2; variants = 4; - envDisabled |= Env.scorching; }}; scrapWallHuge = new Wall("scrap-wall-huge"){{ @@ -1635,21 +1619,18 @@ public class Blocks{ health = 60 * 9 * wallHealthMultiplier; size = 3; variants = 3; - envDisabled |= Env.scorching; }}; scrapWallGigantic = new Wall("scrap-wall-gigantic"){{ requirements(Category.defense, BuildVisibility.sandboxOnly, ItemStack.mult(scrapWall.requirements, 16)); health = 60 * 16 * wallHealthMultiplier; size = 4; - envDisabled |= Env.scorching; }}; thruster = new Thruster("thruster"){{ requirements(Category.defense, BuildVisibility.sandboxOnly, with(Items.scrap, 96)); health = 55 * 16 * wallHealthMultiplier; size = 4; - envDisabled |= Env.scorching; }}; berylliumWall = new Wall("beryllium-wall"){{ diff --git a/core/src/mindustry/content/Planets.java b/core/src/mindustry/content/Planets.java index c5e4531e55..7eec1f10b0 100644 --- a/core/src/mindustry/content/Planets.java +++ b/core/src/mindustry/content/Planets.java @@ -65,7 +65,6 @@ public class Planets{ clearSectorOnLose = true; defaultCore = Blocks.coreBastion; iconColor = Color.valueOf("ff9266"); - hiddenItems.addAll(Items.serpuloItems).removeAll(Items.erekirItems); enemyBuildSpeedMultiplier = 0.4f; //TODO disallowed for now @@ -152,7 +151,6 @@ public class Planets{ startSector = 15; alwaysUnlocked = true; landCloudColor = Pal.spore.cpy().a(0.5f); - hiddenItems.addAll(Items.erekirItems).removeAll(Items.serpuloItems); }}; verilus = makeAsteroid("verlius", sun, Blocks.stoneWall, Blocks.iceWall, 0.5f, 12, 2f, gen -> { diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index b782b8204d..c4e05638b0 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -139,6 +139,16 @@ public class TechTree{ } } + /** Adds the specified database tab to all the content in this tree. */ + public void addDatabaseTab(UnlockableContent tab){ + each(node -> node.content.databaseTabs.add(tab)); + } + + /** Adds the specified planet to the shownPlanets of all the content in this tree. */ + public void addPlanet(Planet planet){ + each(node -> node.content.shownPlanets.add(planet)); + } + public Drawable icon(){ return icon == null ? new TextureRegionDrawable(content.uiIcon) : icon; } diff --git a/core/src/mindustry/core/ContentLoader.java b/core/src/mindustry/core/ContentLoader.java index 1005a4a2b1..377549c4ec 100644 --- a/core/src/mindustry/core/ContentLoader.java +++ b/core/src/mindustry/core/ContentLoader.java @@ -88,6 +88,7 @@ public class ContentLoader{ /** Calls Content#init() on everything. Use only after all modules have been created. */ public void init(){ initialize(Content::init); + initialize(Content::postInit); if(logicVars != null) logicVars.init(); Events.fire(new ContentInitEvent()); } diff --git a/core/src/mindustry/core/GameState.java b/core/src/mindustry/core/GameState.java index 17d3b3bfe9..1066e6d2a6 100644 --- a/core/src/mindustry/core/GameState.java +++ b/core/src/mindustry/core/GameState.java @@ -78,7 +78,7 @@ public class GameState{ } public @Nullable Planet getPlanet(){ - return rules.sector != null ? rules.sector.planet : null; + return rules.sector != null ? rules.sector.planet : rules.planet; } public boolean isEditor(){ diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 59f9b3cdcd..d1c7c5ca60 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -140,10 +140,6 @@ public class Logic implements ApplicationListener{ core.items.set(item, core.block.itemCapacity); } } - - //set up hidden items - state.rules.hiddenBuildItems.clear(); - state.rules.hiddenBuildItems.addAll(state.rules.sector.planet.hiddenItems); } //save settings diff --git a/core/src/mindustry/core/UI.java b/core/src/mindustry/core/UI.java index d634e122b5..085f97d6d8 100644 --- a/core/src/mindustry/core/UI.java +++ b/core/src/mindustry/core/UI.java @@ -158,7 +158,7 @@ public class UI implements ApplicationListener, Loadable{ Core.scene.draw(); if(Core.input.keyTap(KeyCode.mouseLeft) && Core.scene.hasField()){ - Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); + Element e = Core.scene.getHoverElement(); if(!(e instanceof TextField)){ Core.scene.setKeyboardFocus(null); } diff --git a/core/src/mindustry/core/World.java b/core/src/mindustry/core/World.java index 92e3e46a8c..a9e858a0c7 100644 --- a/core/src/mindustry/core/World.java +++ b/core/src/mindustry/core/World.java @@ -321,8 +321,6 @@ public class World{ state.rules.cloudColor = sector.planet.landCloudColor; state.rules.env = sector.planet.defaultEnv; state.rules.planet = sector.planet; - state.rules.hiddenBuildItems.clear(); - state.rules.hiddenBuildItems.addAll(sector.planet.hiddenItems); sector.planet.applyRules(state.rules); sector.info.resources = content.toSeq(); sector.info.resources.sort(Structs.comps(Structs.comparing(Content::getContentType), Structs.comparingInt(c -> c.id))); diff --git a/core/src/mindustry/ctype/Content.java b/core/src/mindustry/ctype/Content.java index 58a75b4dc8..97816377e2 100644 --- a/core/src/mindustry/ctype/Content.java +++ b/core/src/mindustry/ctype/Content.java @@ -25,6 +25,9 @@ public abstract class Content implements Comparable{ /** Called after all content and modules are created. Do not use to load regions or texture data! */ public void init(){} + /** Called after init(). */ + public void postInit(){} + /** * Called after all content is created, only on non-headless versions. * Use for loading regions or other image data. diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index c8eacc4f6a..6cbe82e287 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -35,8 +35,6 @@ public abstract class UnlockableContent extends MappableContent{ public boolean hideDetails = true; /** If false, all icon generation is disabled for this content; createIcons is not called. */ public boolean generateIcons = true; - /** Special logic icon ID. */ - public int iconId = 0; /** How big the content appears in certain selection menus */ public float selectionSize = 24f; /** Icon of the content to use in UI. */ @@ -45,11 +43,24 @@ public abstract class UnlockableContent extends MappableContent{ public TextureRegion fullIcon; /** Override for the full icon. Useful for mod content with duplicate icons. Overrides any other full icon.*/ public String fullOverride = ""; + /** If true, this content will appear in all database tabs. */ + public boolean allDatabaseTabs = false; + /** + * Planets that this content is made for. If empty, a planet is decided based on item requirements. + * Currently, this is only meaningful for blocks. + * */ + public ObjectSet shownPlanets = new ObjectSet<>(); + /** + * Content - usually a planet - that dictates which database tab(s) this content will appear in. + * If nothing is defined, it will use the values in shownPlanets. + * If shownPlanets is also empty, it will use Serpulo as the "default" tab. + * */ + public ObjectSet databaseTabs = new ObjectSet<>(); /** The tech tree node for this content, if applicable. Null if not part of a tech tree. */ public @Nullable TechNode techNode; /** Tech nodes for all trees that this content is part of. */ public Seq techNodes = new Seq<>(); - /** Unlock state. Loaded from settings. Do not modify outside of the constructor. */ + /** Unlock state. Loaded from settings. Do not modify outside the constructor. */ protected boolean unlocked; public UnlockableContent(String name){ @@ -61,6 +72,13 @@ public abstract class UnlockableContent extends MappableContent{ this.unlocked = Core.settings != null && Core.settings.getBool(this.name + "-unlocked", false); } + @Override + public void postInit(){ + super.postInit(); + + databaseTabs.addAll(shownPlanets); + } + @Override public void loadIcon(){ fullIcon = @@ -74,6 +92,10 @@ public abstract class UnlockableContent extends MappableContent{ uiIcon = Core.atlas.find(getContentType().name() + "-" + name + "-ui", fullIcon); } + public boolean isOnPlanet(@Nullable Planet planet){ + return planet == null || shownPlanets.isEmpty() || shownPlanets.contains(planet); + } + public int getLogicId(){ return logicVars.lookupLogicId(this); } diff --git a/core/src/mindustry/editor/MapView.java b/core/src/mindustry/editor/MapView.java index dd1c447f61..4131bc2bcd 100644 --- a/core/src/mindustry/editor/MapView.java +++ b/core/src/mindustry/editor/MapView.java @@ -329,7 +329,7 @@ public class MapView extends Element implements GestureListener{ return Core.scene != null && Core.scene.getKeyboardFocus() != null && Core.scene.getKeyboardFocus().isDescendantOf(ui.editor) && ui.editor.isShown() && tool == EditorTool.zoom && - Core.scene.hit(Core.input.mouse().x, Core.input.mouse().y, true) == this; + Core.scene.getHoverElement() == this; } @Override diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 067ebd0afd..309451907e 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -1370,6 +1370,10 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, /** Called when the block is destroyed. The tile is still intact at this stage. */ public void onDestroyed(){ + if(sound != null){ + sound.stop(); + } + float explosiveness = block.baseExplosiveness; float flammability = 0f; float power = 0f; diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index bd405c793e..6bb08a5245 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -153,8 +153,6 @@ public class Rules{ public ObjectSet revealedBlocks = new ObjectSet<>(); /** Unlocked content names. Only used in multiplayer when the campaign is enabled. */ public ObjectSet researched = new ObjectSet<>(); - /** Block containing these items as requirements are hidden. */ - public ObjectSet hiddenBuildItems = Items.erekirOnlyItems.asSet(); /** In-map objective executor. */ public MapObjectives objectives = new MapObjectives(); /** Flags set by objectives. Used in world processors. */ diff --git a/core/src/mindustry/game/Teams.java b/core/src/mindustry/game/Teams.java index 9fb472bf50..c9a38fcb17 100644 --- a/core/src/mindustry/game/Teams.java +++ b/core/src/mindustry/game/Teams.java @@ -8,6 +8,7 @@ import arc.struct.*; import arc.util.*; import mindustry.*; import mindustry.ai.*; +import mindustry.annotations.Annotations.*; import mindustry.gen.*; import mindustry.type.*; import mindustry.world.*; @@ -359,6 +360,10 @@ public class Teams{ //TODO this may cause a lot of packet spam, optimize? Call.setTeam(build, Team.derelict); + if(build.getPayload() instanceof UnitPayload){ + Call.destroyPayload(build); + } + if(Mathf.chance(0.25)){ Time.run(Mathf.random(0f, 60f * 6f), build::kill); } @@ -425,6 +430,14 @@ public class Teams{ } } + @Remote(called = Loc.server, unreliable = true) + public static void destroyPayload(Building build){ + if(build != null && build.getPayload() instanceof UnitPayload && build.takePayload() instanceof UnitPayload unit){ + unit.dump(); + unit.unit.killed(); + } + } + /** Represents a block made by this team that was destroyed somewhere on the map. * This does not include deconstructed blocks.*/ public static class BlockPlan{ diff --git a/core/src/mindustry/logic/GlobalVars.java b/core/src/mindustry/logic/GlobalVars.java index 3b954d986d..4832be2ce8 100644 --- a/core/src/mindustry/logic/GlobalVars.java +++ b/core/src/mindustry/logic/GlobalVars.java @@ -132,7 +132,9 @@ public class GlobalVars{ } for(UnitType type : Vars.content.units()){ - put("@" + type.name, type); + if(!type.internal){ + put("@" + type.name, type); + } } for(Weather weather : Vars.content.weathers()){ diff --git a/core/src/mindustry/logic/LAssembler.java b/core/src/mindustry/logic/LAssembler.java index 37b79e845f..8af2c4e87f 100644 --- a/core/src/mindustry/logic/LAssembler.java +++ b/core/src/mindustry/logic/LAssembler.java @@ -33,8 +33,9 @@ public class LAssembler{ Seq st = read(data, privileged); - asm.instructions = st.map(l -> l.build(asm)).retainAll(l -> l != null).toArray(LInstruction.class); asm.privileged = privileged; + + asm.instructions = st.map(l -> l.build(asm)).retainAll(l -> l != null).toArray(LInstruction.class); return asm; } @@ -58,7 +59,7 @@ public class LAssembler{ /** @return a variable by name. * This may be a constant variable referring to a number or object. */ public LVar var(String symbol){ - LVar constVar = Vars.logicVars.get(symbol); + LVar constVar = Vars.logicVars.get(symbol, privileged); if(constVar != null) return constVar; symbol = symbol.trim(); diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index c2fc83138b..dd3c0133cd 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -171,7 +171,7 @@ public class LCanvas extends Table{ } StatementElem checkHovered(){ - Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); + Element e = Core.scene.getHoverElement(); if(e != null){ while(e != null && !(e instanceof StatementElem)){ e = e.parent; diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index f57cdffc9e..b3eb8dd628 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -555,7 +555,7 @@ public class LExecutor{ int address = position.numi(); Building from = target.building(); - if(from instanceof MemoryBuild mem && (exec.privileged || from.team == exec.team)){ + if(from instanceof MemoryBuild mem && (exec.privileged || (from.team == exec.team && !mem.block.privileged))){ output.setnum(address < 0 || address >= mem.memory.length ? 0 : mem.memory[address]); } } @@ -662,7 +662,7 @@ public class LExecutor{ LogicAI ai = null; if(base instanceof Ranged r && (exec.privileged || r.team() == exec.team) && - (base instanceof Building || (ai = UnitControlI.checkLogicAI(exec, base)) != null)){ //must be a building or a controllable unit + ((base instanceof Building b && (!b.block.privileged || exec.privileged)) || (ai = UnitControlI.checkLogicAI(exec, base)) != null)){ //must be a building or a controllable unit float range = r.range(); Healthc targeted; @@ -1050,7 +1050,7 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - if(target.building() instanceof MessageBuild d && (d.team == exec.team || exec.privileged)){ + if(target.building() instanceof MessageBuild d && (exec.privileged || (d.team == exec.team && !d.block.privileged))){ d.message.setLength(0); d.message.append(exec.textBuffer, 0, Math.min(exec.textBuffer.length(), maxTextBuffer)); @@ -1242,7 +1242,8 @@ public class LExecutor{ result.setobj(units == null || i < 0 || i >= units.size ? null : units.get(i)); } } - case player -> result.setobj(i < 0 || i >= data.players.size ? null : data.players.get(i).unit()); + case player -> result.setobj(i < 0 || i >= data.players.size ? null : + data.players.get(i).unit() instanceof BlockUnitc block ? block.tile() : data.players.get(i).unit()); case core -> result.setobj(i < 0 || i >= data.cores.size ? null : data.cores.get(i)); case build -> { Block block = extra.obj() instanceof Block b ? b : null; @@ -1295,7 +1296,7 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - Tile tile = world.tile(x.numi(), y.numi()); + Tile tile = world.tile(Mathf.round(x.numf()), Mathf.round(y.numf())); if(tile == null){ dest.setobj(null); }else{ @@ -1380,7 +1381,7 @@ public class LExecutor{ Team t = team.team(); - if(type.obj() instanceof UnitType type && !type.hidden && t != null && Units.canCreate(t, type)){ + if(type.obj() instanceof UnitType type && !type.internal && !type.hidden && t != null && Units.canCreate(t, type)){ //random offset to prevent stacking var unit = type.spawn(t, World.unconv(x.numf()) + Mathf.range(0.01f), World.unconv(y.numf()) + Mathf.range(0.01f)); spawner.spawnEffect(unit, rotation.numf()); diff --git a/core/src/mindustry/maps/generators/BaseGenerator.java b/core/src/mindustry/maps/generators/BaseGenerator.java index 9671a83a42..71ccc7810c 100644 --- a/core/src/mindustry/maps/generators/BaseGenerator.java +++ b/core/src/mindustry/maps/generators/BaseGenerator.java @@ -34,7 +34,7 @@ public class BaseGenerator{ Seq wallsSmall = content.blocks().select(b -> b instanceof Wall && b.isVanilla() && b.size == size && !b.insulated && b.buildVisibility == BuildVisibility.shown && !(b instanceof Door) - && !(Structs.contains(b.requirements, i -> state.rules.hiddenBuildItems.contains(i.item)))); + && b.isOnPlanet(state.getPlanet())); wallsSmall.sort(b -> b.buildCost); return wallsSmall.getFrac(difficulty * 0.91f); } diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 19d033b01c..0395da4e09 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -1097,29 +1097,41 @@ public class ContentParser{ } Field field = metadata.field; try{ - boolean isMap = ObjectMap.class.isAssignableFrom(field.getType()) || ObjectIntMap.class.isAssignableFrom(field.getType()) || ObjectFloatMap.class.isAssignableFrom(field.getType()); - boolean mergeMap = isMap && child.has("add") && child.get("add").isBoolean() && child.getBoolean("add", false); + if(child.isObject() && child.has("add") && (Seq.class.isAssignableFrom(field.getType()) || ObjectSet.class.isAssignableFrom(field.getType()))){ + Object readField = parser.readValue(field.getType(), metadata.elementType, child.get("add"), metadata.keyType); + Object fieldObj = field.get(object); - if(mergeMap){ - child.remove("add"); - } - - Object readField = parser.readValue(field.getType(), metadata.elementType, child, metadata.keyType); - Object fieldObj = field.get(object); - - //if a map has add: true, add its contents to the map instead - if(mergeMap && (fieldObj instanceof ObjectMap || fieldObj instanceof ObjectIntMap || fieldObj instanceof ObjectFloatMap)){ - if(field.get(object) instanceof ObjectMap baseMap){ - baseMap.putAll((ObjectMap)readField); - }else if(field.get(object) instanceof ObjectIntMap baseMap){ - baseMap.putAll((ObjectIntMap)readField); - }else if(field.get(object) instanceof ObjectFloatMap baseMap){ - baseMap.putAll((ObjectFloatMap)readField); + if(fieldObj instanceof ObjectSet set){ + set.addAll((ObjectSet)readField); + }else if(fieldObj instanceof Seq seq){ + seq.addAll((Seq)readField); + }else{ + throw new SerializationException("This should be impossible"); } }else{ - field.set(object, readField); - } + boolean isMap = ObjectMap.class.isAssignableFrom(field.getType()) || ObjectIntMap.class.isAssignableFrom(field.getType()) || ObjectFloatMap.class.isAssignableFrom(field.getType()); + boolean mergeMap = isMap && child.has("add") && child.get("add").isBoolean() && child.getBoolean("add", false); + if(mergeMap){ + child.remove("add"); + } + + Object readField = parser.readValue(field.getType(), metadata.elementType, child, metadata.keyType); + Object fieldObj = field.get(object); + + //if a map has add: true, add its contents to the map instead + if(mergeMap && (fieldObj instanceof ObjectMap || fieldObj instanceof ObjectIntMap || fieldObj instanceof ObjectFloatMap)){ + if(field.get(object) instanceof ObjectMap baseMap){ + baseMap.putAll((ObjectMap)readField); + }else if(field.get(object) instanceof ObjectIntMap baseMap){ + baseMap.putAll((ObjectIntMap)readField); + }else if(field.get(object) instanceof ObjectFloatMap baseMap){ + baseMap.putAll((ObjectFloatMap)readField); + } + }else{ + field.set(object, readField); + } + } }catch(IllegalAccessException ex){ throw new SerializationException("Error accessing field: " + field.getName() + " (" + type.getName() + ")", ex); }catch(SerializationException ex){ diff --git a/core/src/mindustry/service/GameService.java b/core/src/mindustry/service/GameService.java index ce008a3c88..84495f5f77 100644 --- a/core/src/mindustry/service/GameService.java +++ b/core/src/mindustry/service/GameService.java @@ -81,12 +81,12 @@ public class GameService{ } private void registerEvents(){ - allTransportSerpulo = content.blocks().select(b -> b.category == Category.distribution && b.isVisibleOn(Planets.serpulo) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); - allTransportErekir = content.blocks().select(b -> b.category == Category.distribution && b.isVisibleOn(Planets.erekir) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); + allTransportSerpulo = content.blocks().select(b -> b.category == Category.distribution && b.isOnPlanet(Planets.serpulo) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); + allTransportErekir = content.blocks().select(b -> b.category == Category.distribution && b.isOnPlanet(Planets.erekir) && b.isVanilla() && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); //cores are ignored since they're upgrades and can be skipped - allSerpuloBlocks = content.blocks().select(b -> b.synthetic() && b.isVisibleOn(Planets.serpulo) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); - allErekirBlocks = content.blocks().select(b -> b.synthetic() && b.isVisibleOn(Planets.erekir) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); + allSerpuloBlocks = content.blocks().select(b -> b.synthetic() && b.isOnPlanet(Planets.serpulo) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); + allErekirBlocks = content.blocks().select(b -> b.synthetic() && b.isOnPlanet(Planets.erekir) && b.isVanilla() && !(b instanceof CoreBlock) && b.buildVisibility == BuildVisibility.shown).toArray(Block.class); unitsBuilt = Core.settings.getJson("units-built" , ObjectSet.class, String.class, ObjectSet::new); blocksBuilt = Core.settings.getJson("blocks-built" , ObjectSet.class, String.class, ObjectSet::new); @@ -526,7 +526,7 @@ public class GameService{ } for(Building entity : player.team().cores()){ - if(!content.items().contains(i -> !state.rules.hiddenBuildItems.contains(i) && entity.items.get(i) < entity.block.itemCapacity)){ + if(!content.items().contains(i -> i.isOnPlanet(state.getPlanet()) && entity.items.get(i) < entity.block.itemCapacity)){ fillCoreAllCampaign.complete(); break; } diff --git a/core/src/mindustry/type/Item.java b/core/src/mindustry/type/Item.java index 1c59b0d07a..5d81790919 100644 --- a/core/src/mindustry/type/Item.java +++ b/core/src/mindustry/type/Item.java @@ -47,7 +47,9 @@ public class Item extends UnlockableContent implements Senseable{ /** If true, this material is used by buildings. If false, this material will be incinerated in certain cores. */ public boolean buildable = true; public boolean hidden = false; - /** For mods. Adds this item to the listed planets' hidden items Seq. */ + + /** @deprecated no-op, do not use. */ + @Deprecated public @Nullable Planet[] hiddenOnPlanets; public Item(String name, Color color){ @@ -60,14 +62,9 @@ public class Item extends UnlockableContent implements Senseable{ } @Override - public void init(){ - super.init(); - - if(hiddenOnPlanets != null){ - for(Planet planet : hiddenOnPlanets){ - planet.hiddenItems.add(this); - } - } + public boolean isOnPlanet(Planet planet){ + //hidden items should not appear on any planet's resource selection screen + return super.isOnPlanet(planet) && !hidden; } @Override diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index c25852881f..047a288093 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -15,7 +15,6 @@ import mindustry.content.*; import mindustry.content.TechTree.*; import mindustry.ctype.*; import mindustry.game.*; -import mindustry.game.EventType.ContentInitEvent; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.graphics.g3d.*; @@ -146,10 +145,8 @@ public class Planet extends UnlockableContent{ public @Nullable TechNode techTree; /** TODO remove? Planets that can be launched to from this one. Made mutual in init(). */ public Seq launchCandidates = new Seq<>(); - /** Items not available on this planet. Left out for backwards compatibility. */ - public Seq hiddenItems = new Seq<>(); - /** The only items available on this planet, if defined. */ - public Seq itemWhitelist = new Seq<>(); + /** If true, all content in this planet's tech tree will be assigned this planet in their shownPlanets. */ + public boolean autoAssignPlanet = true; /** Content (usually planet-specific) that is unlocked upon landing here. */ public Seq unlockedOnLand = new Seq<>(); /** Loads the mesh. Clientside only. Defaults to a boring sphere mesh. */ @@ -157,6 +154,11 @@ public class Planet extends UnlockableContent{ /** Loads the planet grid outline mesh. Clientside only. */ public Prov gridMeshLoader = () -> MeshBuilder.buildPlanetGrid(grid, outlineColor, outlineRad * radius); + /** @deprecated no-op, do not use. */ + @Deprecated + public Seq itemWhitelist = new Seq<>(), hiddenItems = new Seq<>(); + + public Planet(String name, Planet parent, float radius){ super(name); @@ -179,13 +181,6 @@ public class Planet extends UnlockableContent{ parent.updateTotalRadius(); } - //if an item whitelist exists, add everything else not in that whitelist to hidden items - Events.on(ContentInitEvent.class, e -> { - if(itemWhitelist.size > 0){ - hiddenItems.addAll(content.items().select(i -> !itemWhitelist.contains(i))); - } - }); - //calculate solar system for(solarSystem = this; solarSystem.parent != null; solarSystem = solarSystem.parent); } @@ -216,8 +211,6 @@ public class Planet extends UnlockableContent{ rules.attributes.add(defaultAttributes); rules.env = defaultEnv; rules.planet = this; - rules.hiddenBuildItems.clear(); - rules.hiddenBuildItems.addAll(hiddenItems); } public @Nullable Sector getLastSector(){ @@ -338,6 +331,11 @@ public class Planet extends UnlockableContent{ techTree = TechTree.roots.find(n -> n.planet == this); } + if(techTree != null && autoAssignPlanet){ + techTree.addDatabaseTab(this); + techTree.addPlanet(this); + } + for(Sector sector : sectors){ sector.loadInfo(); } diff --git a/core/src/mindustry/type/StatusEffect.java b/core/src/mindustry/type/StatusEffect.java index 79d0177b41..0e36616cd4 100644 --- a/core/src/mindustry/type/StatusEffect.java +++ b/core/src/mindustry/type/StatusEffect.java @@ -68,10 +68,12 @@ public class StatusEffect extends UnlockableContent{ public StatusEffect(String name){ super(name); + allDatabaseTabs = true; } @Override public void init(){ + super.init(); if(initblock != null){ initblock.run(); } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 3408948807..15ed66ce9c 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -675,6 +675,8 @@ public class UnitType extends UnlockableContent implements Senseable{ @CallSuper @Override public void init(){ + super.init(); + if(constructor == null) throw new IllegalArgumentException("no constructor set up for unit '" + name + "'"); Unit example = constructor.get(); diff --git a/core/src/mindustry/ui/Minimap.java b/core/src/mindustry/ui/Minimap.java index 99c7a32303..ee03fc2435 100644 --- a/core/src/mindustry/ui/Minimap.java +++ b/core/src/mindustry/ui/Minimap.java @@ -111,7 +111,7 @@ public class Minimap extends Table{ update(() -> { - Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); + Element e = Core.scene.getHoverElement(); if(e != null && e.isDescendantOf(this)){ requestScroll(); }else if(hasScroll()){ diff --git a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java index a277593dd3..6ae81fc338 100644 --- a/core/src/mindustry/ui/dialogs/CustomRulesDialog.java +++ b/core/src/mindustry/ui/dialogs/CustomRulesDialog.java @@ -229,19 +229,8 @@ public class CustomRulesDialog extends BaseDialog{ } number("@rules.dropzoneradius", false, f -> rules.dropZoneRadius = f * tilesize, () -> rules.dropZoneRadius / tilesize, () -> rules.waves); - category("resourcesbuilding"); - check("@rules.infiniteresources", b -> { - rules.infiniteResources = b; - - //reset to serpulo if any env was enabled - if(!b && rules.hiddenBuildItems.isEmpty()){ - rules.env = Planets.serpulo.defaultEnv; - rules.hiddenBuildItems.clear(); - rules.hiddenBuildItems.addAll(Planets.serpulo.hiddenItems); - setup(); - } - }, () -> rules.infiniteResources); + check("@rules.infiniteresources", b -> rules.infiniteResources = b, () -> rules.infiniteResources); check("@rules.onlydepositcore", b -> rules.onlyDepositCore = b, () -> rules.onlyDepositCore); check("@rules.derelictrepair", b -> rules.derelictRepair = b, () -> rules.derelictRepair); check("@rules.reactorexplosions", b -> rules.reactorExplosions = b, () -> rules.reactorExplosions); @@ -349,7 +338,6 @@ public class CustomRulesDialog extends BaseDialog{ t.button("@rules.anyenv", style, () -> { rules.env = Vars.defaultEnv; - rules.hiddenBuildItems.clear(); rules.planet = Planets.sun; }).group(group).checked(b -> rules.planet == Planets.sun); }).left().fill(false).expand(false, false).row(); diff --git a/core/src/mindustry/ui/dialogs/DatabaseDialog.java b/core/src/mindustry/ui/dialogs/DatabaseDialog.java index 9fdefa9e1c..e8ffe18778 100644 --- a/core/src/mindustry/ui/dialogs/DatabaseDialog.java +++ b/core/src/mindustry/ui/dialogs/DatabaseDialog.java @@ -5,11 +5,13 @@ import arc.graphics.*; import arc.input.*; import arc.math.*; import arc.scene.event.*; +import arc.scene.style.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; import arc.util.*; import mindustry.*; +import mindustry.content.*; import mindustry.ctype.*; import mindustry.gen.*; import mindustry.graphics.*; @@ -24,16 +26,30 @@ public class DatabaseDialog extends BaseDialog{ private TextField search; private Table all = new Table(); + private @Nullable Seq allTabs; + //sun means "all content" + private UnlockableContent tab = Planets.sun; + public DatabaseDialog(){ super("@database"); shouldPause = true; addCloseButton(); - shown(this::rebuild); + shown(() -> { + checkTabList(); + if(state.isCampaign() && allTabs.contains(state.getPlanet())){ + tab = state.getPlanet(); + }else if(state.isGame() && state.rules.planet != null && allTabs.contains(state.rules.planet)){ + tab = state.rules.planet; + } + + rebuild(); + }); onResize(this::rebuild); all.margin(20).marginTop(0f); + cont.top(); cont.table(s -> { s.image(Icon.zoom).padRight(8); search = s.field(null, text -> rebuild()).growX().get(); @@ -43,18 +59,51 @@ public class DatabaseDialog extends BaseDialog{ cont.pane(all).scrollX(false); } + void checkTabList(){ + if(allTabs == null){ + Seq[] allContent = Vars.content.getContentMap(); + ObjectSet all = new ObjectSet<>(); + for(var contents : allContent){ + for(var content : contents){ + if(content instanceof UnlockableContent u){ + all.addAll(u.databaseTabs); + } + } + } + allTabs = all.toSeq().sort(); + allTabs.insert(0, Planets.sun); + } + } + void rebuild(){ + checkTabList(); + all.clear(); var text = search.getText().toLowerCase(); Seq[] allContent = Vars.content.getContentMap(); + all.table(t -> { + int i = 0; + for(var content : allTabs){ + t.button(content == Planets.sun ? Icon.eyeSmall : content instanceof Planet ? Icon.planet : new TextureRegionDrawable(content.uiIcon), Styles.clearNoneTogglei, iconMed, () -> { + tab = content; + rebuild(); + }).size(50f).checked(b -> tab == content).tooltip(content == Planets.sun ? "@all" : content.localizedName).with(but -> { + but.getStyle().imageUpColor = content instanceof Planet p ? p.iconColor : Color.white.cpy(); + }); + + if(++i % 10 == 0) t.row(); + } + }).row();; + for(int j = 0; j < allContent.length; j++){ ContentType type = ContentType.all[j]; Seq array = allContent[j] - .select(c -> c instanceof UnlockableContent u && !u.isHidden() && + .select(c -> c instanceof UnlockableContent u && !u.isHidden() && (tab == Planets.sun || u.allDatabaseTabs || u.databaseTabs.contains(tab)) && (text.isEmpty() || u.localizedName.toLowerCase().contains(text))).as(); + if(array.size == 0) continue; all.add("@content." + type.name() + ".name").growX().left().color(Pal.accent); diff --git a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java index 61d3358233..1b309e05b6 100644 --- a/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java +++ b/core/src/mindustry/ui/dialogs/LaunchLoadoutDialog.java @@ -48,7 +48,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ ItemSeq launch = universe.getLaunchResources(); if(sector.planet.allowLaunchLoadout){ for(var item : content.items()){ - if(sector.planet.hiddenItems.contains(item)){ + if(!item.isOnPlanet(sector.planet)){ launch.set(item, 0); } } @@ -72,7 +72,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ if(destination.preset != null){ var rules = destination.preset.generator.map.rules(); for(var stack : rules.loadout){ - if(!sector.planet.hiddenItems.contains(stack.item)){ + if(stack.item.isOnPlanet(sector.planet)){ resources.add(stack.item, stack.amount); } } @@ -136,7 +136,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ ItemSeq realItems = sitems.copy(); selected.requirements().each(realItems::remove); - loadout.show(lastCapacity, realItems, out, i -> i.unlocked() && !sector.planet.hiddenItems.contains(i), out::clear, () -> {}, () -> { + loadout.show(lastCapacity, realItems, out, i -> i.unlocked() && i.isOnPlanet(sector.planet), out::clear, () -> {}, () -> { universe.updateLaunchResources(new ItemSeq(out)); update.run(); rebuildItems.run(); @@ -172,7 +172,7 @@ public class LaunchLoadoutDialog extends BaseDialog{ Cons handler = s -> { if(s.tiles.contains(tile -> !tile.block.supportsEnv(sector.planet.defaultEnv) || //make sure block can be built here. - (!sector.planet.hiddenItems.isEmpty() && Structs.contains(tile.block.requirements, stack -> sector.planet.hiddenItems.contains(stack.item))))){ + !tile.block.isOnPlanet(sector.planet))){ return; } diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index c8f4fb44c2..6ef9bb6397 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -587,7 +587,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ @Override public void act(float delta){ - if(scene.getDialog() == PlanetDialog.this && !scene.hit(input.mouseX(), input.mouseY(), true).isDescendantOf(e -> e instanceof ScrollPane)){ + if(scene.getDialog() == PlanetDialog.this && (scene.getHoverElement() == null || !scene.getHoverElement().isDescendantOf(e -> e instanceof ScrollPane))){ scene.setScrollFocus(PlanetDialog.this); } diff --git a/core/src/mindustry/ui/dialogs/ResearchDialog.java b/core/src/mindustry/ui/dialogs/ResearchDialog.java index a251419f31..e601e02b5d 100644 --- a/core/src/mindustry/ui/dialogs/ResearchDialog.java +++ b/core/src/mindustry/ui/dialogs/ResearchDialog.java @@ -472,7 +472,7 @@ public class ResearchDialog extends BaseDialog{ if(mobile){ tapped(() -> { - Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); + Element e = Core.scene.getHoverElement(); if(e == this){ hoverNode = null; rebuild(); diff --git a/core/src/mindustry/ui/fragments/BlockConfigFragment.java b/core/src/mindustry/ui/fragments/BlockConfigFragment.java index 356c63fca4..79ad799a3a 100644 --- a/core/src/mindustry/ui/fragments/BlockConfigFragment.java +++ b/core/src/mindustry/ui/fragments/BlockConfigFragment.java @@ -67,7 +67,7 @@ public class BlockConfigFragment{ } public boolean hasConfigMouse(){ - Element e = Core.scene.hit(Core.input.mouseX(), Core.graphics.getHeight() - Core.input.mouseY(), true); + Element e = Core.scene.getHoverElement(); return e != null && (e == table || e.isDescendantOf(table)); } diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index 2c3e6ad524..8bbc475022 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -615,7 +615,7 @@ public class PlacementFragment{ blocksSelect.margin(4).marginTop(0); blockPane = blocksSelect.pane(blocks -> blockTable = blocks).height(194f).update(pane -> { if(pane.hasScroll()){ - Element result = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); + Element result = Core.scene.getHoverElement(); if(result == null || !result.isDescendantOf(pane)){ Core.scene.setScrollFocus(null); } diff --git a/core/src/mindustry/world/Block.java b/core/src/mindustry/world/Block.java index 1576cfb162..c324ae4978 100644 --- a/core/src/mindustry/world/Block.java +++ b/core/src/mindustry/world/Block.java @@ -899,10 +899,6 @@ public class Block extends UnlockableContent implements Senseable{ return !isHidden() && (state.rules.editor || (!state.rules.hideBannedBlocks || !state.rules.isBanned(this))); } - public boolean isVisibleOn(Planet planet){ - return !Structs.contains(requirements, i -> planet.hiddenItems.contains(i.item)); - } - public boolean isPlaceable(){ return isVisible() && (!state.rules.isBanned(this) || state.rules.editor) && supportsEnv(state.rules.env); } @@ -948,7 +944,7 @@ public class Block extends UnlockableContent implements Senseable{ } public boolean environmentBuildable(){ - return (state.rules.hiddenBuildItems.isEmpty() || !Structs.contains(requirements, i -> state.rules.hiddenBuildItems.contains(i.item))); + return isOnPlanet(state.getPlanet()); } public boolean isStatic(){ @@ -1164,10 +1160,28 @@ public class Block extends UnlockableContent implements Senseable{ return buildVisibility != BuildVisibility.hidden; } + @Override + public void postInit(){ + //usually, an empty set of planets is a configuration error. auto-assign based on requirements + if(requirements.length > 0 && shownPlanets.isEmpty()){ + for(Planet planet : content.planets()){ + if(planet.isLandable()){ + if(!Structs.contains(requirements, s -> !s.item.isOnPlanet(planet))){ + shownPlanets.add(planet); + } + } + } + } + + super.postInit(); + } + /** Called after all blocks are created. */ @Override @CallSuper public void init(){ + super.init(); + //disable standard shadow if(customShadow){ hasShadow = false; diff --git a/core/src/mindustry/world/blocks/ItemSelection.java b/core/src/mindustry/world/blocks/ItemSelection.java index 483ba28134..24e49706de 100644 --- a/core/src/mindustry/world/blocks/ItemSelection.java +++ b/core/src/mindustry/world/blocks/ItemSelection.java @@ -9,7 +9,6 @@ import arc.struct.*; import arc.util.*; import mindustry.ctype.*; import mindustry.gen.*; -import mindustry.type.*; import mindustry.ui.*; import mindustry.world.*; @@ -65,7 +64,7 @@ public class ItemSelection{ Seq list = items.select(u -> (text.isEmpty() || u.localizedName.toLowerCase().contains(text.toLowerCase()))); for(T item : list){ - if(!item.unlockedNow() || (item instanceof Item checkVisible && state.rules.hiddenBuildItems.contains(checkVisible)) || item.isHidden()) continue; + if(!item.unlockedNow() || !item.isOnPlanet(state.getPlanet()) || item.isHidden()) continue; ImageButton button = cont.button(Tex.whiteui, Styles.clearNoneTogglei, Mathf.clamp(item.selectionSize, 0f, 40f), () -> { if(closeSelect) control.input.config.hideConfig(); diff --git a/core/src/mindustry/world/blocks/defense/ForceProjector.java b/core/src/mindustry/world/blocks/defense/ForceProjector.java index 74f0fd4860..58ee4b6c2d 100644 --- a/core/src/mindustry/world/blocks/defense/ForceProjector.java +++ b/core/src/mindustry/world/blocks/defense/ForceProjector.java @@ -6,6 +6,7 @@ import arc.graphics.*; import arc.graphics.g2d.*; import arc.math.*; import arc.math.geom.*; +import arc.struct.*; import arc.util.*; import arc.util.io.*; import mindustry.annotations.Annotations.*; @@ -266,6 +267,14 @@ public class ForceProjector extends Block{ Draw.reset(); } + @Override + public void overwrote(Seq previous){ + if(previous.size > 0 && previous.first().block == block && previous.first() instanceof ForceBuild b){ + broken = b.broken; + buildup = b.buildup; + } + } + @Override public void write(Writes write){ super.write(write); diff --git a/core/src/mindustry/world/blocks/payloads/BuildPayload.java b/core/src/mindustry/world/blocks/payloads/BuildPayload.java index 90e37e9e16..57d0812e8c 100644 --- a/core/src/mindustry/world/blocks/payloads/BuildPayload.java +++ b/core/src/mindustry/world/blocks/payloads/BuildPayload.java @@ -53,6 +53,7 @@ public class BuildPayload implements Payload{ @Override public void destroyed(){ + build.dead = true; build.onDestroyed(); } diff --git a/gradle.properties b/gradle.properties index 1aee74fc4a..17ec33f127 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ org.gradle.caching=true org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 android.enableR8.fullMode=false -archash=3f26197a0c +archash=aafecc8a29125e70255e6cdb34a92690531d1a57 diff --git a/servers_v7.json b/servers_v7.json index da2f7648c0..98193f0a53 100644 --- a/servers_v7.json +++ b/servers_v7.json @@ -1,4 +1,8 @@ [ + { + "name": "EscoCorp", + "address": ["81.30.105.171:6567"] + }, { "name": "Redundancy Dept", "address": ["min7.include-once.org:8000", "min7.include-once.org:8001"] @@ -73,7 +77,7 @@ }, { "name": "SMoke of Anarchy", - "address": ["86.102.97.27"] + "address": ["mindustry.smokeofanarchy.ru", "mindustry.smokeofanarchy.ru:6568", "mindustry.smokeofanarchy.ru:6569", "mindustry.smokeofanarchy.ru:6570", "mindustry.smokeofanarchy.ru:6571", "mindustry.smokeofanarchy.ru:6572", "mindustry.smokeofanarchy.ru:6573", "mindustry.smokeofanarchy.ru:6574", "mindustry.smokeofanarchy.ru:6575", "mindustry.smokeofanarchy.ru:6576"] }, { "name": "Mindustry.pl", @@ -246,7 +250,7 @@ }, { "name": "abcxyz remaster", - "address": ["144.76.57.59:30302", "23.88.73.88:16895"] + "address": ["144.76.57.59:35150", "23.88.73.88:11066", "23.88.73.88:9171", "23.88.73.88:10911"] }, { "name": "CroCraft Network", @@ -282,11 +286,11 @@ }, { "name": "AZDustry", - "address": ["8.245.23.28:25874"] + "address": ["148.251.77.197:2012"] }, { "name": "Erepulo", - "address": ["95.84.198.97:5401", "95.84.198.97:5402", "95.84.198.97:5403", "95.84.198.97:5404", "95.84.198.97:2357", "95.84.198.97:5500"] + "address": ["95.84.198.97:5401", "95.84.198.97:5402", "95.84.198.97:5403", "95.84.198.97:5404", "95.84.198.97:2357", "95.84.198.97:5500", "199.83.103.251"] }, { "name": "MineCore",