From c7db8dc6251e93a2c59d6afb39596d10c3518605 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 10 Jul 2025 22:22:57 -0400 Subject: [PATCH 1/6] Better zoom clamp for planets --- core/src/mindustry/type/Planet.java | 2 ++ core/src/mindustry/ui/dialogs/PlanetDialog.java | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index 502cd0286d..1b4e1cdafc 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -58,6 +58,8 @@ public class Planet extends UnlockableContent{ public float camRadius; /** Minimum camera zoom value. */ public float minZoom = 0.5f; + /** Maximum camera zoom value. */ + public float maxZoom = 2f; /** Whether to draw the orbital circle. */ public boolean drawOrbit = true; /** Atmosphere radius adjustment parameters. */ diff --git a/core/src/mindustry/ui/dialogs/PlanetDialog.java b/core/src/mindustry/ui/dialogs/PlanetDialog.java index 1b18bc31db..4f623af694 100644 --- a/core/src/mindustry/ui/dialogs/PlanetDialog.java +++ b/core/src/mindustry/ui/dialogs/PlanetDialog.java @@ -85,6 +85,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ state.planet = content.getByName(ContentType.planet, Core.settings.getString("lastplanet", "serpulo")); if(state.planet == null) state.planet = Planets.serpulo; + clampZoom(); + addListener(new InputListener(){ @Override public boolean keyDown(InputEvent event, KeyCode key){ @@ -140,7 +142,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ @Override public boolean scrolled(InputEvent event, float x, float y, float amountX, float amountY){ if(event.targetActor == PlanetDialog.this){ - zoom = Mathf.clamp(zoom + amountY / 10f, state.planet.minZoom, 2f); + zoom = Mathf.clamp(zoom + amountY / 10f, state.planet.minZoom, state.planet.maxZoom); } return true; } @@ -155,7 +157,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ lastZoom = zoom; } - zoom = (Mathf.clamp(initialDistance / distance * lastZoom, state.planet.minZoom, 2f)); + zoom = (Mathf.clamp(initialDistance / distance * lastZoom, state.planet.minZoom, state.planet.maxZoom)); } @Override @@ -396,6 +398,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ //TODO should this even set `state.planet`? the other lookAt() doesn't, so... state.planet = sector.planet; sector.planet.lookAt(sector, state.camPos); + + clampZoom(); } public void lookAt(Sector sector, float alpha){ @@ -403,6 +407,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ state.camPos.slerp(sector.planet.lookAt(sector, Tmp.v33).setLength(len), alpha); } + void clampZoom(){ + zoom = Mathf.clamp(zoom, state.planet.minZoom, state.planet.maxZoom); + } + boolean canSelect(Sector sector){ if(mode == select) return sector.hasBase() && launchSector != null && sector.planet == launchSector.planet; @@ -872,6 +880,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{ newPresets.clear(); state.planet = planet; + clampZoom(); + selected = null; updateSelected(); rebuildExpand(); From f5f19339234d3ba8efb5eaa108011f7ea6e064d5 Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 11 Jul 2025 10:56:25 -0400 Subject: [PATCH 2/6] Mining units now search for the closest ore to the core, not themselves --- core/src/mindustry/ai/types/MinerAI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/ai/types/MinerAI.java b/core/src/mindustry/ai/types/MinerAI.java index 4cbf671bc2..a560250172 100644 --- a/core/src/mindustry/ai/types/MinerAI.java +++ b/core/src/mindustry/ai/types/MinerAI.java @@ -55,8 +55,8 @@ public class MinerAI extends AIController{ }else{ if(timer.get(timerTarget3, 60) && targetItem != null){ ore = null; - if(unit.type.mineFloor) ore = indexer.findClosestOre(unit, targetItem); - if(ore == null && unit.type.mineWalls) ore = indexer.findClosestWallOre(unit, targetItem); + if(unit.type.mineFloor) ore = indexer.findClosestOre(core.x, core.y, targetItem); + if(ore == null && unit.type.mineWalls) ore = indexer.findClosestWallOre(core.x, core.y, targetItem); } if(ore != null){ From 0539d00cda3b86a1950cafe962eddba458bac78c Mon Sep 17 00:00:00 2001 From: Anuken Date: Fri, 11 Jul 2025 11:51:55 -0400 Subject: [PATCH 3/6] Re-added non-indexed mesh support --- .../mindustry/graphics/g3d/MeshBuilder.java | 71 ++++++++++++------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/core/src/mindustry/graphics/g3d/MeshBuilder.java b/core/src/mindustry/graphics/g3d/MeshBuilder.java index cb9be7b418..fc5fd4664d 100644 --- a/core/src/mindustry/graphics/g3d/MeshBuilder.java +++ b/core/src/mindustry/graphics/g3d/MeshBuilder.java @@ -91,9 +91,9 @@ public class MeshBuilder{ boolean emit = mesher.isEmissive(); - if(grid.tiles.length * 6 >= 65535) throw new RuntimeException("Due to index size limits, only meshes with a maximum of 65535 vertices are supported. If you want more than that, make your own non-indexed mesh builder."); + boolean indexed = grid.tiles.length * 6 < 65535; - Mesh mesh = begin(grid.tiles.length * 6, grid.tiles.length * 4 * 3, true, emit); + Mesh mesh = begin(indexed ? grid.tiles.length * 6 : grid.tiles.length * 12, indexed ? grid.tiles.length * 4 * 3 : 0, true, emit); float[] heights; @@ -109,7 +109,7 @@ public class MeshBuilder{ } int position = 0; - short[] shorts = new short[12]; + short[] shorts = indexed ? new short[12] : null; float[] floats = new float[3 + (gl30 ? 1 : 3) + 1 + (emit ? 1 : 0)]; Vec3 nor = new Vec3(); @@ -150,32 +150,43 @@ public class MeshBuilder{ emissive = tmpCol.toFloatBits(); } - for(var corner : c){ - float height = heights[corner.id]; + if(indexed){ + for(var corner : c){ + float height = heights[corner.id]; - vert(mesh, floats, corner.v.x * height, corner.v.y * height, corner.v.z * height, nor, color, emissive); + vert(mesh, floats, corner.v.x * height, corner.v.y * height, corner.v.z * height, nor, color, emissive); + } + + shorts[0] = (short)(position); + shorts[1] = (short)(position + 1); + shorts[2] = (short)(position + 2); + + shorts[3] = (short)(position); + shorts[4] = (short)(position + 2); + shorts[5] = (short)(position + 3); + + shorts[6] = (short)(position); + shorts[7] = (short)(position + 3); + shorts[8] = (short)(position + 4); + + if(c.length > 5){ + shorts[9] = (short)(position); + shorts[10] = (short)(position + 4); + shorts[11] = (short)(position + 5); + } + + mesh.getIndicesBuffer().put(shorts, 0, c.length > 5 ? 12 : 9); + + position += c.length; + }else{ + verts(mesh, floats, c[0].v, heights[c[0].id], c[1].v, heights[c[1].id], c[2].v, heights[c[2].id], nor, color, emissive); + verts(mesh, floats, c[0].v, heights[c[0].id], c[2].v, heights[c[2].id], c[3].v, heights[c[3].id], nor, color, emissive); + verts(mesh, floats, c[0].v, heights[c[0].id], c[3].v, heights[c[3].id], c[4].v, heights[c[4].id], nor, color, emissive); + + if(c.length > 5){ + verts(mesh, floats, c[0].v, heights[c[0].id], c[4].v, heights[c[4].id], c[5].v, heights[c[5].id], nor, color, emissive); + } } - - shorts[0] = (short)(position); - shorts[1] = (short)(position + 1); - shorts[2] = (short)(position + 2); - - shorts[3] = (short)(position); - shorts[4] = (short)(position + 2); - shorts[5] = (short)(position + 3); - - shorts[6] = (short)(position); - shorts[7] = (short)(position + 3); - shorts[8] = (short)(position + 4); - - if(c.length > 5){ - shorts[9] = (short)(position); - shorts[10] = (short)(position + 4); - shorts[11] = (short)(position + 5); - } - - mesh.getIndicesBuffer().put(shorts, 0, c.length > 5 ? 12 : 9); - position += c.length; } return end(mesh); @@ -240,6 +251,12 @@ public class MeshBuilder{ out.set(cx, cy, cz).nor(); } + private static void verts(Mesh mesh, float[] floats, Vec3 a, float h1, Vec3 b, float h2, Vec3 c, float h3, Vec3 normal, float color, float emissive){ + vert(mesh, floats, a.x * h1, a.y * h1, a.z * h1, normal, color, emissive); + vert(mesh, floats, b.x * h2, b.y * h2, b.z * h2, normal, color, emissive); + vert(mesh, floats, c.x * h3, c.y * h3, c.z * h3, normal, color, emissive); + } + private static void vert(Mesh mesh, float[] floats, float x, float y, float z, Vec3 normal, float color, float emissive){ floats[0] = x; floats[1] = y; From aeee327e6c1a09c1a8b4baae7ea84f9ee9b964a4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 12 Jul 2025 12:42:05 -0400 Subject: [PATCH 4/6] Fixed #11009 --- core/src/mindustry/ai/BlockIndexer.java | 67 +++++++++++++------------ 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/core/src/mindustry/ai/BlockIndexer.java b/core/src/mindustry/ai/BlockIndexer.java index e6a498808a..11278ddac6 100644 --- a/core/src/mindustry/ai/BlockIndexer.java +++ b/core/src/mindustry/ai/BlockIndexer.java @@ -203,43 +203,44 @@ public class BlockIndexer{ } } - public void addIndex(Tile tile){ - process(tile); + public void addIndex(Tile base){ + process(base); - Item drop = tile.drop(), wallDrop = tile.wallDrop(); - if(drop == null && wallDrop == null) return; - int qx = tile.x / quadrantSize, qy = tile.y / quadrantSize; - int pos = tile.pos(); + base.getLinkedTiles(tile -> { + Item drop = tile.drop(), wallDrop = tile.wallDrop(); + if(drop == null && wallDrop == null) return; + int qx = tile.x / quadrantSize, qy = tile.y / quadrantSize; + int pos = tile.pos(); - if(tile.block() == Blocks.air){ - if(drop != null){ //floor - if(ores[drop.id] == null) ores[drop.id] = new IntSeq[quadWidth][quadHeight]; - if(ores[drop.id][qx][qy] == null) ores[drop.id][qx][qy] = new IntSeq(false, 16); - if(ores[drop.id][qx][qy].addUnique(pos)){ - int old = allOres.increment(drop); //increment ore count only if not already counted - if(old == 0) updatePresentOres(); + if(tile.block() == Blocks.air){ + if(drop != null){ //floor + if(ores[drop.id] == null) ores[drop.id] = new IntSeq[quadWidth][quadHeight]; + if(ores[drop.id][qx][qy] == null) ores[drop.id][qx][qy] = new IntSeq(false, 16); + if(ores[drop.id][qx][qy].addUnique(pos)){ + int old = allOres.increment(drop); //increment ore count only if not already counted + if(old == 0) updatePresentOres(); + } + } + if(wallDrop != null && wallOres != null && wallOres[wallDrop.id] != null && wallOres[wallDrop.id][qx][qy] != null && wallOres[wallDrop.id][qx][qy].removeValue(pos)){ //wall + int old = allWallOres.increment(wallDrop, -1); + if(old == 1) updatePresentOres(); + } + }else{ + if(wallDrop != null){ //wall + if(wallOres[wallDrop.id] == null) wallOres[wallDrop.id] = new IntSeq[quadWidth][quadHeight]; + if(wallOres[wallDrop.id][qx][qy] == null) wallOres[wallDrop.id][qx][qy] = new IntSeq(false, 16); + if(wallOres[wallDrop.id][qx][qy].addUnique(pos)){ + int old = allWallOres.increment(wallDrop); //increment ore count only if not already counted + if(old == 0) updatePresentOres(); + } + } + + if(drop != null && ores != null && ores[drop.id] != null && ores[drop.id][qx][qy] != null && ores[drop.id][qx][qy].removeValue(pos)){ //floor + int old = allOres.increment(drop, -1); + if(old == 1) updatePresentOres(); } } - if(wallDrop != null && wallOres != null && wallOres[wallDrop.id] != null && wallOres[wallDrop.id][qx][qy] != null && wallOres[wallDrop.id][qx][qy].removeValue(pos)){ //wall - int old = allWallOres.increment(wallDrop, -1); - if(old == 1) updatePresentOres(); - } - }else{ - if(wallDrop != null){ //wall - if(wallOres[wallDrop.id] == null) wallOres[wallDrop.id] = new IntSeq[quadWidth][quadHeight]; - if(wallOres[wallDrop.id][qx][qy] == null) wallOres[wallDrop.id][qx][qy] = new IntSeq(false, 16); - if(wallOres[wallDrop.id][qx][qy].addUnique(pos)){ - int old = allWallOres.increment(wallDrop); //increment ore count only if not already counted - if(old == 0) updatePresentOres(); - } - } - - if(drop != null && ores != null && ores[drop.id] != null && ores[drop.id][qx][qy] != null && ores[drop.id][qx][qy].removeValue(pos)){ //floor - int old = allOres.increment(drop, -1); - if(old == 1) updatePresentOres(); - } - } - + }); } /** @return whether a certain block is anywhere on this map. */ From 086933614b2c6d156ba2a8db3070e3f6efbc8de1 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 12 Jul 2025 14:26:02 -0400 Subject: [PATCH 5/6] Better pathfinder allDeep calculation --- core/src/mindustry/ai/Pathfinder.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/mindustry/ai/Pathfinder.java b/core/src/mindustry/ai/Pathfinder.java index 3ee3ee55d5..b131897f54 100644 --- a/core/src/mindustry/ai/Pathfinder.java +++ b/core/src/mindustry/ai/Pathfinder.java @@ -239,6 +239,17 @@ public class Pathfinder implements Runnable{ } } + //check diagonals for allDeep + if(allDeep){ + for(int i = 0; i < 4; i++){ + Tile other = tile.nearby(Geometry.d8edge[i]); + if(other != null && !other.floor().isDeep()){ + allDeep = false; + break; + } + } + } + int tid = tile.getTeamID(); return PathTile.get( From 95a6850ce5c9436f2227ac84799aad5dd3e84fd8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 15 Jul 2025 10:58:20 -0400 Subject: [PATCH 6/6] Reverted power node build time multiplier / No mono global selection --- core/src/mindustry/content/Blocks.java | 1 - core/src/mindustry/content/UnitTypes.java | 1 + core/src/mindustry/input/DesktopInput.java | 6 +++--- core/src/mindustry/type/UnitType.java | 2 ++ gradle.properties | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index a935307e19..ed97b6c8d0 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -2311,7 +2311,6 @@ public class Blocks{ requirements(Category.power, with(Items.copper, 2, Items.lead, 6)); maxNodes = 10; laserRange = 6; - buildCostMultiplier = 2.5f; }}; powerNodeLarge = new PowerNode("power-node-large"){{ diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 113193b15a..3662857a13 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1267,6 +1267,7 @@ public class UnitTypes{ engineOffset = 5.7f; range = 50f; isEnemy = false; + controlSelectGlobal = false; ammoType = new PowerAmmoType(500); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index cdada0ed26..1a400df68f 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -306,10 +306,10 @@ public class DesktopInput extends InputHandler{ commandBuildings.clear(); if(input.keyDown(Binding.selectAcrossScreen)){ camera.bounds(Tmp.r1); - selectedUnits.set(selectedCommandUnits(Tmp.r1.x, Tmp.r1.y, Tmp.r1.width, Tmp.r1.height)); + selectedUnits.set(selectedCommandUnits(Tmp.r1.x, Tmp.r1.y, Tmp.r1.width, Tmp.r1.height).removeAll(u -> !u.type.controlSelectGlobal)); }else { for(var unit : player.team().data().units){ - if(unit.isCommandable()){ + if(unit.isCommandable() && unit.type.controlSelectGlobal){ selectedUnits.add(unit); } } @@ -325,7 +325,7 @@ public class DesktopInput extends InputHandler{ selectedUnits.set(selectedCommandUnits(Tmp.r1.x, Tmp.r1.y, Tmp.r1.width, Tmp.r1.height, u -> u instanceof Payloadc)); }else { for(var unit : player.team().data().units){ - if(unit.isCommandable() && unit instanceof Payloadc){ + if(unit.isCommandable() && unit instanceof Payloadc){ selectedUnits.add(unit); } } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 4a782b3002..edb903a331 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -178,6 +178,8 @@ public class UnitType extends UnlockableContent implements Senseable{ logicControllable = true, /** if false, players cannot control this unit */ playerControllable = true, + /** If true, the unit can be selected with the global selection hotkey (shift+g). */ + controlSelectGlobal = true, /** if false, this unit cannot be moved into payloads */ allowedInPayloads = true, /** if false, this unit cannot be hit by bullets or explosions*/ diff --git a/gradle.properties b/gradle.properties index 543e664edd..5e1d3a2b35 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=bd8d9520a4 +archash=ae3b50eaca