From 9d9d5d2e18739e15d8f2f6cbceb2b78ee8134d99 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 20 Sep 2023 22:45:45 -0400 Subject: [PATCH] Patrol + pursue target stances --- core/assets/bundles/bundle.properties | 2 ++ core/src/mindustry/ai/UnitStance.java | 4 +++- core/src/mindustry/ai/types/CommandAI.java | 13 ++++++++++++- core/src/mindustry/content/UnitTypes.java | 2 ++ core/src/mindustry/mod/ContentParser.java | 12 ++++++++++++ core/src/mindustry/type/UnitType.java | 4 ++-- .../mindustry/ui/fragments/PlacementFragment.java | 5 ++++- 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 346b0cbdea..4ca489cea3 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -356,6 +356,8 @@ command.boost = Boost stance.stop = Cancel Orders stance.shoot = Stance: Shoot stance.holdfire = Stance: Hold Fire +stance.pursuetarget = Stance: Pursue Target +stance.patrol = Stance: Patrol Path openlink = Open Link copylink = Copy Link back = Back diff --git a/core/src/mindustry/ai/UnitStance.java b/core/src/mindustry/ai/UnitStance.java index c7bbc69241..3f164edb47 100644 --- a/core/src/mindustry/ai/UnitStance.java +++ b/core/src/mindustry/ai/UnitStance.java @@ -13,7 +13,9 @@ public class UnitStance{ stopStance = new UnitStance("stop", "cancel"), //not a real stance, cannot be selected, just cancels ordewrs shootStance = new UnitStance("shoot", "commandAttack"), - holdFireStance = new UnitStance("holdfire", "none"); + holdFireStance = new UnitStance("holdfire", "none"), + pursueTarget = new UnitStance("pursuetarget", "right"), + patrol = new UnitStance("patrol", "refresh"); /** Unique ID number. */ public final int id; diff --git a/core/src/mindustry/ai/types/CommandAI.java b/core/src/mindustry/ai/types/CommandAI.java index bb012445cf..dddc90a068 100644 --- a/core/src/mindustry/ai/types/CommandAI.java +++ b/core/src/mindustry/ai/types/CommandAI.java @@ -67,6 +67,10 @@ public class CommandAI extends AIController{ //this should not be possible if(stance == UnitStance.stopStance) stance = UnitStance.shootStance; + if(stance == UnitStance.pursueTarget && target != null && attackTarget == null && targetPos == null){ + commandTarget(target, false); + } + //remove invalid targets if(commandQueue.any()){ commandQueue.removeAll(e -> e instanceof Healthc h && !h.isValid()); @@ -194,11 +198,13 @@ public class CommandAI extends AIController{ target = attackTarget; circleAttack(80f); }else{ + boolean isFinalPoint = targetPos.epsilonEquals(vecOut, 4.1f) && commandQueue.size == 0; + moveTo(vecOut, attackTarget != null && unit.within(attackTarget, engageRange) ? engageRange : unit.isGrounded() ? 0f : attackTarget != null ? engageRange : - 0f, unit.isFlying() ? 40f : 100f, false, null, targetPos.epsilonEquals(vecOut, 4.1f)); + 0f, unit.isFlying() ? 40f : 100f, false, null, isFinalPoint); } } @@ -243,6 +249,7 @@ public class CommandAI extends AIController{ } void finishPath(){ + Vec2 prev = targetPos; targetPos = null; if(commandQueue.size > 0){ var next = commandQueue.remove(0); @@ -251,6 +258,10 @@ public class CommandAI extends AIController{ }else if(next instanceof Vec2 position){ commandPosition(position); } + + if(prev != null && stance == UnitStance.patrol){ + commandQueue.add(prev.cpy()); + } } } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index a72a14ef90..f92f5397a2 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1285,6 +1285,7 @@ public class UnitTypes{ lowAltitude = true; ammoType = new PowerAmmoType(900); + stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance}; mineTier = 2; mineSpeed = 3.5f; @@ -1344,6 +1345,7 @@ public class UnitTypes{ isEnemy = false; ammoType = new PowerAmmoType(1100); + stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance}; weapons.add( new Weapon("heal-weapon-mount"){{ diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 8bb9efb643..aa18db1675 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -122,6 +122,18 @@ public class ContentParser{ throw new IllegalArgumentException("Unit commands must be strings."); } }); + put(UnitStance.class, (type, data) -> { + if(data.isString()){ + var cmd = UnitStance.all.find(u -> u.name.equals(data.asString())); + if(cmd != null){ + return cmd; + }else{ + throw new IllegalArgumentException("Unknown unit stance name: " + data.asString()); + } + }else{ + throw new IllegalArgumentException("Unit stances must be strings."); + } + }); put(BulletType.class, (type, data) -> { if(data.isString()){ return field(Bullets.class, data); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 9a486773c5..46f19e1920 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -836,9 +836,9 @@ public class UnitType extends UnlockableContent implements Senseable{ if(stances.length == 0){ if(canAttack){ - stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance}; + stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance, UnitStance.pursueTarget, UnitStance.patrol}; }else{ - stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance}; + stances = new UnitStance[]{UnitStance.stopStance}; } } diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index b3390df5e5..695654fb85 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -524,12 +524,15 @@ public class PlacementFragment{ } //list stances - if(stances.size > 0){ + if(stances.size > 1){ u.row(); u.table(coms -> { coms.left(); for(var stance : stances){ + //TODO: patrolling is pointless on mobile since you can't queue commands + if(stance == UnitStance.patrol && mobile) continue; + coms.button(Icon.icons.get(stance.icon, Icon.cancel), Styles.clearNoneTogglei, () -> { IntSeq ids = new IntSeq(); for(var unit : units){