From 8c0f50acb696e560a1d0e0579011759d0699dffd Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 30 Oct 2022 15:10:23 -0400 Subject: [PATCH] Support for selecting multiple buildings to command --- core/src/mindustry/input/InputHandler.java | 70 +++++++++++++--------- core/src/mindustry/input/MobileInput.java | 4 +- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index d2630c9593..f66c57ae76 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -82,7 +82,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ //for RTS controls public Seq selectedUnits = new Seq<>(); - public @Nullable Building commandBuild; + public Seq commandBuildings = new Seq<>(false); public boolean commandMode = false; public boolean commandRect = false; public boolean tappedOne = false; @@ -279,21 +279,28 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(called = Loc.server, targets = Loc.both, forward = true) - public static void commandBuilding(Player player, Building build, Vec2 target){ - if(player == null || build == null || build.team != player.team() || !build.block.commandable || target == null) return; + public static void commandBuilding(Player player, int[] buildings, Vec2 target){ + if(player == null || target == null) return; - if(net.server() && !netServer.admins.allowAction(player, ActionType.commandBuilding, event -> { - event.tile = build.tile; - })){ - throw new ValidateException(player, "Player cannot command building."); + for(int pos : buildings){ + var build = world.build(pos); + + if(build == null || build.team() != player.team() || !build.block.commandable) continue; + + if(net.server() && !netServer.admins.allowAction(player, ActionType.commandBuilding, event -> { + event.tile = build.tile; + })){ + throw new ValidateException(player, "Player cannot command building."); + } + + build.onCommand(target); + if(!state.isPaused() && player == Vars.player){ + Fx.moveCommand.at(target); + } + + Events.fire(new BuildingCommandEvent(player, build, target)); } - build.onCommand(target); - if(!state.isPaused() && player == Vars.player){ - Fx.moveCommand.at(target); - } - - Events.fire(new BuildingCommandEvent(player, build, target)); } @Remote(called = Loc.server, targets = Loc.both, forward = true) @@ -633,9 +640,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ logicCutsceneZoom = -1f; } - if(commandBuild != null && !commandBuild.isValid()){ - commandBuild = null; - } + commandBuildings.removeAll(b -> !b.isValid()); if(!commandMode){ commandRect = false; @@ -768,7 +773,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } selectedUnits.addAll(units); Events.fire(Trigger.unitCommandChange); - commandBuild = null; + commandBuildings.clear(); } commandRect = false; } @@ -797,15 +802,20 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ }else{ selectedUnits.remove(unit); } - commandBuild = null; + commandBuildings.clear(); }else{ //deselect selectedUnits.clear(); if(build != null && build.team == player.team() && build.block.commandable){ - commandBuild = (commandBuild == build ? null : build); + if(commandBuildings.contains(build)){ + commandBuildings.remove(build); + }else{ + commandBuildings.add(build); + } + }else{ - commandBuild = null; + commandBuildings.clear(); } } Events.fire(Trigger.unitCommandChange); @@ -839,8 +849,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Call.commandUnits(player, ids, attack instanceof Building b ? b : null, attack instanceof Unit u ? u : null, target); } - if(commandBuild != null){ - Call.commandBuilding(player, commandBuild, target); + if(commandBuildings.size > 0){ + Call.commandBuilding(player, commandBuildings.mapInt(b -> b.pos()).toArray(), target); } } } @@ -875,13 +885,15 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } } - if(commandBuild != null){ - Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f); - var cpos = commandBuild.getCommandPosition(); + for(var commandBuild : commandBuildings){ + if(commandBuild != null){ + Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f); + var cpos = commandBuild.getCommandPosition(); - if(cpos != null){ - Drawf.limitLine(commandBuild, cpos, commandBuild.hitSize() / 2f, 3.5f); - Drawf.square(cpos.x, cpos.y, 3.5f); + if(cpos != null){ + Drawf.limitLine(commandBuild, cpos, commandBuild.hitSize() / 2f, 3.5f); + Drawf.square(cpos.x, cpos.y, 3.5f); + } } } @@ -1334,7 +1346,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(build == null){ inv.hide(); config.hideConfig(); - commandBuild = null; + commandBuildings.clear(); return false; } boolean consumed = false, showedInventory = false; diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index d8a596288a..489ec70add 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -646,7 +646,7 @@ public class MobileInput extends InputHandler implements GestureListener{ }else if(mode == breaking && validBreak(linked.x,linked.y) && !hasPlan(linked)){ //add to selection queue if it's a valid BREAK position selectPlans.add(new BuildPlan(linked.x, linked.y)); - }else if((commandMode && selectedUnits.size > 0) || commandBuild != null){ + }else if((commandMode && selectedUnits.size > 0) || commandBuildings.size > 0){ //handle selecting units with command mode commandTap(x, y); }else if(commandMode){ @@ -715,7 +715,7 @@ public class MobileInput extends InputHandler implements GestureListener{ selectedUnits.removeAll(u -> !u.isCommandable() || !u.isValid()); if(!commandMode){ - commandBuild = null; + commandBuildings.clear(); selectedUnits.clear(); }