From a6ec8f4bcc5feaf36696c69567c2aa02973d2155 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 21 Sep 2023 09:57:57 -0400 Subject: [PATCH] Ram stance + Mobile command queue support --- core/assets/bundles/bundle.properties | 2 ++ core/src/mindustry/ai/UnitStance.java | 3 ++- core/src/mindustry/ai/types/CommandAI.java | 8 +++---- core/src/mindustry/content/UnitTypes.java | 4 ++-- core/src/mindustry/game/Teams.java | 2 ++ core/src/mindustry/input/MobileInput.java | 24 ++++++++++++++----- core/src/mindustry/type/UnitType.java | 6 ++++- core/src/mindustry/ui/Styles.java | 12 ++++++++++ .../ui/fragments/PlacementFragment.java | 9 +++++-- 9 files changed, 54 insertions(+), 16 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 4ca489cea3..ca8a6683ac 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -347,6 +347,7 @@ open = Open customize = Customize Rules cancel = Cancel command = Command +command.queue = [lightgray][Queuing] command.mine = Mine command.repair = Repair command.rebuild = Rebuild @@ -358,6 +359,7 @@ stance.shoot = Stance: Shoot stance.holdfire = Stance: Hold Fire stance.pursuetarget = Stance: Pursue Target stance.patrol = Stance: Patrol Path +stance.ram = Stance: Ram\n[lightgray]Straight line movement, no pathfinding 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 3f164edb47..5dc28dd2cb 100644 --- a/core/src/mindustry/ai/UnitStance.java +++ b/core/src/mindustry/ai/UnitStance.java @@ -15,7 +15,8 @@ public class UnitStance{ shootStance = new UnitStance("shoot", "commandAttack"), holdFireStance = new UnitStance("holdfire", "none"), pursueTarget = new UnitStance("pursuetarget", "right"), - patrol = new UnitStance("patrol", "refresh"); + patrol = new UnitStance("patrol", "refresh"), + ram = new UnitStance("ram", "rightOpen"); /** 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 dddc90a068..7c45323d41 100644 --- a/core/src/mindustry/ai/types/CommandAI.java +++ b/core/src/mindustry/ai/types/CommandAI.java @@ -165,7 +165,7 @@ public class CommandAI extends AIController{ } targetPos.set(attackTarget); - if(unit.isGrounded() && attackTarget instanceof Building build && build.tile.solid() && unit.pathType() != Pathfinder.costLegs){ + if(unit.isGrounded() && attackTarget instanceof Building build && build.tile.solid() && unit.pathType() != Pathfinder.costLegs && stance != UnitStance.ram){ Tile best = build.findClosestEdge(unit, Tile::solid); if(best != null){ targetPos.set(best); @@ -177,7 +177,7 @@ public class CommandAI extends AIController{ boolean move = true; vecOut.set(targetPos); - if(unit.isGrounded()){ + if(unit.isGrounded() && stance != UnitStance.ram){ move = Vars.controlPath.getPathPosition(unit, pathId, targetPos, vecOut, noFound); //if the path is invalid, stop trying and record the end as unreachable @@ -201,9 +201,9 @@ public class CommandAI extends AIController{ boolean isFinalPoint = targetPos.epsilonEquals(vecOut, 4.1f) && commandQueue.size == 0; moveTo(vecOut, - attackTarget != null && unit.within(attackTarget, engageRange) ? engageRange : + attackTarget != null && unit.within(attackTarget, engageRange) && stance != UnitStance.ram ? engageRange : unit.isGrounded() ? 0f : - attackTarget != null ? engageRange : + attackTarget != null && stance != UnitStance.ram ? engageRange : 0f, unit.isFlying() ? 40f : 100f, false, null, isFinalPoint); } } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index f92f5397a2..cb1709b5fb 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1285,7 +1285,7 @@ public class UnitTypes{ lowAltitude = true; ammoType = new PowerAmmoType(900); - stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance}; + stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance, UnitStance.patrol}; mineTier = 2; mineSpeed = 3.5f; @@ -1345,7 +1345,7 @@ public class UnitTypes{ isEnemy = false; ammoType = new PowerAmmoType(1100); - stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance}; + stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance, UnitStance.patrol}; weapons.add( new Weapon("heal-weapon-mount"){{ diff --git a/core/src/mindustry/game/Teams.java b/core/src/mindustry/game/Teams.java index e47b5bfb13..8e37437883 100644 --- a/core/src/mindustry/game/Teams.java +++ b/core/src/mindustry/game/Teams.java @@ -307,6 +307,8 @@ public class Teams{ //convert all team tiles to neutral, randomly killing them for(var b : builds){ + if(b.block.privileged) continue; + if(b instanceof CoreBuild){ b.kill(); }else{ diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index dfac50b02c..358d08547e 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -54,8 +54,8 @@ public class MobileInput extends InputHandler implements GestureListener{ public Seq removals = new Seq<>(); /** Whether the player is currently shifting all placed tiles. */ public boolean selecting; - /** Whether the player is currently in line-place mode. */ - public boolean lineMode, schematicMode, rebuildMode; + /** Various modes that aren't enums for some reason. This should be cleaned up. */ + public boolean lineMode, schematicMode, rebuildMode, queueCommandMode; /** Current place mode. */ public PlaceMode mode = none; /** Whether no recipe was available when switching to break mode. */ @@ -287,16 +287,24 @@ public class MobileInput extends InputHandler implements GestureListener{ group.fill(t -> { t.visible(() -> !showCancel() && block == null && !hasSchem()); t.bottom().left(); - t.button("@command", Icon.units, Styles.squareTogglet, () -> { + + t.button("@command", Icon.units, Styles.clearTogglet, () -> { commandMode = !commandMode; - }).width(155f).height(50f).margin(12f).checked(b -> commandMode).row(); + }).width(155f).height(56f).margin(12f).checked(b -> { + b.setText(queueCommandMode ? bundle.get("command") + "\n" + bundle.get("command.queue") : bundle.get("command")); + return commandMode; + }); + + t.button(Icon.rightOpen, Styles.clearTogglei, () -> { + queueCommandMode = !queueCommandMode; + }).size(56f).margin(12f).checked(b -> queueCommandMode).visible(() -> commandMode).row(); //for better looking insets t.rect((x, y, w, h) -> { if(Core.scene.marginBottom > 0){ Tex.paneRight.draw(x, 0, w, y); } - }).fillX().row(); + }).fillX().colspan(2).row(); }); group.fill(t -> { @@ -681,7 +689,7 @@ public class MobileInput extends InputHandler implements GestureListener{ selectPlans.add(new BuildPlan(linked.x, linked.y)); }else if((commandMode && selectedUnits.size > 0) || commandBuildings.size > 0){ //handle selecting units with command mode - commandTap(x, y); + commandTap(x, y, queueCommandMode); }else if(commandMode){ tapCommandUnit(); }else{ @@ -734,6 +742,10 @@ public class MobileInput extends InputHandler implements GestureListener{ boolean locked = locked(); + if(!commandMode){ + queueCommandMode = false; + } + if(player.dead()){ mode = none; manualShooting = false; diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 46f19e1920..70aa8ab95c 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -836,7 +836,11 @@ public class UnitType extends UnlockableContent implements Senseable{ if(stances.length == 0){ if(canAttack){ - stances = new UnitStance[]{UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance, UnitStance.pursueTarget, UnitStance.patrol}; + Seq seq = Seq.with(UnitStance.stopStance, UnitStance.shootStance, UnitStance.holdFireStance, UnitStance.pursueTarget, UnitStance.patrol); + if(crushDamage > 0){ + seq.add(UnitStance.ram); + } + stances = seq.toArray(UnitStance.class); }else{ stances = new UnitStance[]{UnitStance.stopStance}; } diff --git a/core/src/mindustry/ui/Styles.java b/core/src/mindustry/ui/Styles.java index 8f608edda3..416aeb3c2b 100644 --- a/core/src/mindustry/ui/Styles.java +++ b/core/src/mindustry/ui/Styles.java @@ -48,6 +48,8 @@ public class Styles{ togglet, /** Partially transparent square button. */ cleart, + /** Clear, square, orange border, toggleable. */ + clearTogglet, /** Similar to flatToggle, but without a darker border. */ fullTogglet, /** Toggle-able version of flatBorder. */ @@ -219,6 +221,16 @@ public class Styles{ disabled = buttonDisabled; disabledFontColor = Color.gray; }}; + clearTogglet = new TextButtonStyle(){{ + font = Fonts.def; + fontColor = Color.white; + down = flatDown; + checked = flatDown; + up = black6; + over = flatOver; + disabled = black; + disabledFontColor = Color.gray; + }}; fullTogglet = new TextButtonStyle(){{ font = Fonts.def; fontColor = Color.white; diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index 695654fb85..9f03e527f4 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -510,6 +510,7 @@ public class PlacementFragment{ u.table(coms -> { coms.left(); + int scol = 0; for(var command : commands){ coms.button(Icon.icons.get(command.icon, Icon.cancel), Styles.clearNoneTogglei, () -> { IntSeq ids = new IntSeq(); @@ -519,7 +520,10 @@ public class PlacementFragment{ Call.setUnitCommand(Vars.player, ids.toArray(), command); }).checked(i -> currentCommand[0] == command).size(50f).tooltip(command.localized()); + + if(++scol % 6 == 0) coms.row(); } + }).fillX().padTop(4f).left(); } @@ -529,9 +533,8 @@ public class PlacementFragment{ u.table(coms -> { coms.left(); + int scol = 0; 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(); @@ -541,6 +544,8 @@ public class PlacementFragment{ Call.setUnitStance(Vars.player, ids.toArray(), stance); }).checked(i -> currentStance[0] == stance).size(50f).tooltip(stance.localized()); + + if(++scol % 6 == 0) coms.row(); } }).fillX().padTop(4f).left(); }