diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java index b3e35a21d1..0f2cb8c5e8 100644 --- a/core/src/mindustry/ai/types/FlyingAI.java +++ b/core/src/mindustry/ai/types/FlyingAI.java @@ -33,16 +33,24 @@ public class FlyingAI extends AIController{ @Override protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){ - Teamc result = target(x, y, range, air, ground); - if(result != null) return result; + var result = findMainTarget(x, y, range, air, ground); - if(ground) result = targetFlag(x, y, BlockFlag.generator, true); - if(result != null) return result; + //if the main target is in range, use it, otherwise target whatever is closest + return checkTarget(result, x, y, range) ? target(x, y, range, air, ground) : result; + } - if(ground) result = targetFlag(x, y, BlockFlag.core, true); - if(result != null) return result; - - return null; + @Override + protected Teamc findMainTarget(float x, float y, float range, boolean air, boolean ground){ + for(var flag : unit.team.isAI() ? unit.type.targetFlags : unit.type.playerTargetFlags){ + if(flag == null){ + Teamc result = target(x, y, range, air, ground); + if(result != null) return result; + }else if(ground){ + Teamc result = targetFlag(x, y, flag, true); + if(result != null) return result; + } + } + return targetFlag(x, y, BlockFlag.core, true); } protected void attack(float circleLength){ diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 8749c7f4e9..b218b1c483 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -928,6 +928,7 @@ public class UnitTypes implements ContentList{ engineOffset = 5.5f; range = 140f; targetAir = false; + targetFlags = new BlockFlag[]{BlockFlag.generator, null}; commandLimit = 4; circleTarget = true; hitSize = 7; @@ -961,7 +962,7 @@ public class UnitTypes implements ContentList{ range = 140f; faceTarget = false; armor = 3f; - targetFlag = BlockFlag.factory; + targetFlags = new BlockFlag[]{BlockFlag.factory, null}; commandLimit = 5; circleTarget = true; @@ -999,6 +1000,7 @@ public class UnitTypes implements ContentList{ lowAltitude = true; armor = 5f; + targetFlags = new BlockFlag[]{BlockFlag.launchPad, BlockFlag.storage, BlockFlag.battery, null}; engineOffset = 12f; engineSize = 3f; @@ -1045,7 +1047,7 @@ public class UnitTypes implements ContentList{ engineOffset = 21; engineSize = 5.3f; hitSize = 46f; - targetFlag = BlockFlag.battery; + targetFlags = new BlockFlag[]{BlockFlag.generator, BlockFlag.core, null}; BulletType missiles = new MissileBulletType(2.7f, 14){{ width = 8f; @@ -1120,7 +1122,7 @@ public class UnitTypes implements ContentList{ hitSize = 58f; destructibleWreck = false; armor = 13f; - targetFlag = BlockFlag.reactor; + targetFlags = new BlockFlag[]{BlockFlag.reactor, BlockFlag.core, null}; BulletType fragBullet = new FlakBulletType(4f, 5){{ shootEffect = Fx.shootBig; @@ -1333,7 +1335,7 @@ public class UnitTypes implements ContentList{ buildBeamOffset = 23; range = 140f; targetAir = false; - targetFlag = BlockFlag.battery; + targetFlags = new BlockFlag[]{BlockFlag.battery, BlockFlag.factory, null}; ammoType = AmmoTypes.powerHigh; diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index e4d2bfaf2b..c1764052da 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -79,7 +79,6 @@ public class AIController implements UnitController{ return Units.invalidateTarget(target, unit.team, unit.x, unit.y); } - protected void pathfind(int pathTarget){ int costType = unit.pathType(); @@ -97,7 +96,7 @@ public class AIController implements UnitController{ boolean ret = retarget(); if(ret){ - target = findTarget(unit.x, unit.y, unit.range(), unit.type.targetAir, unit.type.targetGround); + target = findMainTarget(unit.x, unit.y, unit.range(), unit.type.targetAir, unit.type.targetGround); } if(invalid(target)){ @@ -167,6 +166,10 @@ public class AIController implements UnitController{ return timer.get(timerTarget, target == null ? 40 : 90); } + protected Teamc findMainTarget(float x, float y, float range, boolean air, boolean ground){ + return findTarget(x, y, range, air, ground); + } + protected Teamc findTarget(float x, float y, float range, boolean air, boolean ground){ return target(x, y, range, air, ground); } diff --git a/core/src/mindustry/game/Team.java b/core/src/mindustry/game/Team.java index e8141d6063..c7c70cda01 100644 --- a/core/src/mindustry/game/Team.java +++ b/core/src/mindustry/game/Team.java @@ -96,6 +96,11 @@ public class Team implements Comparable{ return state.teams.isActive(this); } + /** @return whether this team is solely comprised of AI, with no players. */ + public boolean isAI(){ + return state.rules.waves && this == state.rules.waveTeam; + } + public boolean isEnemy(Team other){ return this != other; } diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index da238f0584..b3f15477b0 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -73,7 +73,10 @@ public class UnitType extends UnlockableContent{ public Effect fallThrusterEffect = Fx.fallSmoke; public Effect deathExplosionEffect = Fx.dynamicExplosion; public Seq abilities = new Seq<>(); - public BlockFlag targetFlag = BlockFlag.generator; + /** Flags to target based on priority. Null indicates that the closest target should be found. The closest enemy core is used as a fallback. */ + public BlockFlag[] targetFlags = {null}; + /** targetFlags, as an override for "non-AI" teams. By default, units of this type will rush the core. */ + public BlockFlag[] playerTargetFlags = {BlockFlag.core, null}; public Color outlineColor = Pal.darkerMetal; public int outlineRadius = 3;