JSON Unit type requirements cache fix / Better FlyingAI flag targeting

This commit is contained in:
Anuken
2026-01-16 17:31:18 -05:00
parent d6495dda32
commit 4f9ea8b70d
8 changed files with 105 additions and 29 deletions

View File

@@ -2,7 +2,6 @@ package mindustry.ai.types;
import arc.math.*;
import mindustry.entities.units.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.world.meta.*;
@@ -31,30 +30,6 @@ public class FlyingAI extends AIController{
}
}
@Override
public Teamc targetFlag(float x, float y, BlockFlag flag, boolean enemy){
if(state.rules.randomWaveAI){
if(unit.team == Team.derelict) return null;
var list = enemy ? indexer.getEnemy(unit.team, flag) : indexer.getFlagged(unit.team, flag);
if(list.isEmpty()) return null;
Building closest = null;
float cdist = 0f;
for(Building t : list){
if(((t.items != null && t.items.any()) || t.status() != BlockStatus.noInput) && t.block.targetable){
float dst = t.dst2(x, y);
if(closest == null || dst < cdist){
closest = t;
cdist = dst;
}
}
}
return closest;
}else{
return super.targetFlag(x, y, flag, enemy);
}
}
@Override
public Teamc findTarget(float x, float y, float range, boolean air, boolean ground){
var result = findMainTarget(x, y, range, air, ground);
@@ -76,7 +51,7 @@ public class FlyingAI extends AIController{
rand.setSeed(unit.type.id + (state.rules.waves ? state.wave : unit.id));
//try a few random flags first
for(int attempt = 0; attempt < 5; attempt++){
Teamc result = targetFlag(x, y, randomTargets[rand.random(randomTargets.length - 1)], true);
Teamc result = targetFlagActive(x, y, randomTargets[rand.random(randomTargets.length - 1)], true);
if(result != null) return result;
}
//try the closest target
@@ -88,7 +63,7 @@ public class FlyingAI extends AIController{
Teamc result = target(x, y, range, air, ground);
if(result != null) return result;
}else if(ground){
Teamc result = targetFlag(x, y, flag, true);
Teamc result = targetFlagActive(x, y, flag, true);
if(result != null) return result;
}
}

View File

@@ -264,6 +264,11 @@ public class AIController implements UnitController{
return Geometry.findClosest(x, y, enemy ? indexer.getEnemy(unit.team, flag) : indexer.getFlagged(unit.team, flag));
}
public Teamc targetFlagActive(float x, float y, BlockFlag flag, boolean enemy){
if(unit.team == Team.derelict) return null;
return Geometry.findClosest(x, y, enemy ? indexer.getEnemy(unit.team, flag) : indexer.getFlagged(unit.team, flag), t -> ((t.items != null && t.items.any()) || t.status() != BlockStatus.noInput) && t.block.targetable);
}
public Teamc target(float x, float y, float range, boolean air, boolean ground){
return Units.closestTarget(unit.team, x, y, range, u -> u.checkTarget(air, ground), t -> ground && (unit.type.targetUnderBlocks || !t.block.underBullets));
}

View File

@@ -313,6 +313,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(content == null) content = Items.copper;
}
@Override
public String toString(){
return "research: " + content;
}
}
/** Produce a specific piece of content in the tech tree (essentially research with different text). */
@@ -339,6 +344,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(content == null) content = Items.copper;
}
@Override
public String toString(){
return "produce: " + content;
}
}
/** Have a certain amount of item in your core. */
@@ -367,6 +377,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(item == null) item = Items.copper;
}
@Override
public String toString(){
return "item: " + item + " x" + amount;
}
}
/** Get a certain item in your core (through a block, not manually.) */
@@ -395,6 +410,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(item == null) item = Items.copper;
}
@Override
public String toString(){
return "coreItem: " + item + " x" + amount;
}
}
/** Build a certain amount of a block. */
@@ -423,6 +443,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(block == null) block = Blocks.conveyor;
}
@Override
public String toString(){
return "buildCount: " + block + " x" + count;
}
}
/** Produce a certain amount of a unit. */
@@ -451,6 +476,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(unit == null) unit = UnitTypes.dagger;
}
@Override
public String toString(){
return "unitCount: " + unit + " x" + count;
}
}
/** Produce a certain amount of units. */
@@ -472,6 +502,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public String text(){
return Core.bundle.format("objective.destroyunits", count - state.stats.enemyUnitsDestroyed);
}
@Override
public String toString(){
return "destroyUnits: " + count;
}
}
public static class TimerObjective extends MapObjective{
@@ -539,6 +574,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
return null;
}
@Override
public String toString(){
return "timer: " + duration;
}
}
public static class DestroyBlockObjective extends MapObjective{
@@ -569,6 +609,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(block == null) block = Blocks.router;
}
@Override
public String toString(){
return "destroyBlock: " + block + ":" + team + " " + pos;
}
}
public static class DestroyBlocksObjective extends MapObjective{
@@ -609,6 +654,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public void validate(){
if(block == null) block = Blocks.router;
}
@Override
public String toString(){
return "destroyBlocks: " + block + ":" + team + " " + Arrays.toString(positions);
}
}
/** Command any unit to do anything. Always compete in headless mode. */
@@ -622,6 +672,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public String text(){
return Core.bundle.get("objective.command");
}
@Override
public String toString(){
return "commandMode";
}
}
/** Wait until a logic flag is set. */
@@ -653,6 +708,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
return text;
}
}
@Override
public String toString(){
return "flag: " + flag;
}
}
/** Destroy all enemy core(s). */
@@ -666,6 +726,11 @@ public class MapObjectives implements Iterable<MapObjective>, Eachable<MapObject
public String text(){
return Core.bundle.get("objective.destroycore");
}
@Override
public String toString(){
return "destroyCore";
}
}
/** Marker used for drawing various content to indicate something along with an objective. Mostly used as UI overlay. */

View File

@@ -29,6 +29,11 @@ public class Objectives{
(content.techNode == null || content.techNode.parent == null || content.techNode.parent.content.unlockedHost()) ?
(content.emoji() + " " + content.localizedName) : "???");
}
@Override
public String toString(){
return "research: " + content;
}
}
public static class Produce implements Objective{
@@ -50,6 +55,11 @@ public class Objectives{
return Core.bundle.format("requirement.produce",
content.unlockedHost() ? (content.emoji() + " " + content.localizedName) : "???");
}
@Override
public String toString(){
return "produce: " + content;
}
}
public static class SectorComplete implements Objective{
@@ -70,6 +80,11 @@ public class Objectives{
public String display(){
return Core.bundle.format("requirement.capture", preset.localizedName);
}
@Override
public String toString(){
return "sectorComplete: " + preset;
}
}
public static class OnSector implements Objective{
@@ -90,6 +105,11 @@ public class Objectives{
public String display(){
return Core.bundle.format("requirement.onsector", preset.localizedName);
}
@Override
public String toString(){
return "onSector: " + preset;
}
}
public static class OnPlanet implements Objective{
@@ -110,6 +130,11 @@ public class Objectives{
public String display(){
return Core.bundle.format("requirement.onplanet", planet.localizedName);
}
@Override
public String toString(){
return "onPlanet: " + planet;
}
}
/** Defines a specific objective for a game. */

View File

@@ -1939,7 +1939,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
&& !player.dead()
&& player.unit().validMine(tile)
&& player.unit().acceptsItem(player.unit().getMineResult(tile))
&& !((!Core.settings.getBool("doubletapmine") && tile.floor().playerUnmineable) && tile.overlay().itemDrop == null);
&& !((!Core.settings.getBool("doubletapmine") && tile.floor().playerUnmineable) && tile.overlay().itemDrop == null)
&& !((!Core.settings.getBool("doubletapmine") && tile.overlay().playerUnmineable) && tile.overlay().itemDrop != null);
}
/** Returns the tile at the specified MOUSE coordinates. */

View File

@@ -616,6 +616,7 @@ public class ContentParser{
currentContent = unit;
read(() -> {
unit.beforeParse();
//add reconstructor type
if(value.has("requirements")){
JsonValue rec = value.remove("requirements");

View File

@@ -1301,6 +1301,10 @@ public class UnitType extends UnlockableContent implements Senseable{
initPathType();
}
public void beforeParse(){
totalRequirements = cachedRequirements = firstRequirements = null;
}
/** @return the time required to build this unit, as a value that takes into account reconstructors */
public float getBuildTime(){
getTotalRequirements();