Merge branch 'master' of https://github.com/Anuken/Mindustry into crux-floor

This commit is contained in:
Anuken
2025-07-15 11:03:19 -04:00
10 changed files with 111 additions and 68 deletions

View File

@@ -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. */

View File

@@ -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(

View File

@@ -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){

View File

@@ -2386,7 +2386,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"){{

View File

@@ -1267,6 +1267,7 @@ public class UnitTypes{
engineOffset = 5.7f;
range = 50f;
isEnemy = false;
controlSelectGlobal = false;
ammoType = new PowerAmmoType(500);

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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. */

View File

@@ -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*/

View File

@@ -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();