JSON Unit type requirements cache fix / Better FlyingAI flag targeting
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -616,6 +616,7 @@ public class ContentParser{
|
||||
|
||||
currentContent = unit;
|
||||
read(() -> {
|
||||
unit.beforeParse();
|
||||
//add reconstructor type
|
||||
if(value.has("requirements")){
|
||||
JsonValue rec = value.remove("requirements");
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user