RTS Control groups
This commit is contained in:
@@ -14,6 +14,7 @@ public enum Binding implements KeyBind{
|
||||
boost(KeyCode.shiftLeft),
|
||||
command_mode(KeyCode.shiftLeft),
|
||||
command_queue(KeyCode.mouseMiddle),
|
||||
create_control_group(KeyCode.controlLeft),
|
||||
control(KeyCode.controlLeft),
|
||||
respawn(KeyCode.v),
|
||||
select(KeyCode.mouseLeft),
|
||||
|
||||
@@ -11,6 +11,7 @@ import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.scene.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.core.*;
|
||||
@@ -22,6 +23,7 @@ import mindustry.graphics.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
import static arc.Core.camera;
|
||||
import static arc.Core.*;
|
||||
import static mindustry.Vars.*;
|
||||
import static mindustry.input.PlaceMode.*;
|
||||
@@ -49,6 +51,11 @@ public class DesktopInput extends InputHandler{
|
||||
/** Previously selected tile. */
|
||||
public Tile prevSelected;
|
||||
|
||||
/** Most recently selected control group by index */
|
||||
public int lastCtrlGroup;
|
||||
/** Time of most recent control group selection */
|
||||
public long lastCtrlGroupSelectMillis;
|
||||
|
||||
boolean showHint(){
|
||||
return ui.hudfrag.shown && Core.settings.getBool("hints") && selectPlans.isEmpty() &&
|
||||
(!isBuilding && !Core.settings.getBool("buildautopause") || player.unit().isBuilding() || !player.dead() && !player.unit().spawnedByCore());
|
||||
@@ -262,22 +269,86 @@ public class DesktopInput extends InputHandler{
|
||||
//validate commanding units
|
||||
selectedUnits.removeAll(u -> !u.isCommandable() || !u.isValid());
|
||||
|
||||
if(commandMode && input.keyTap(Binding.select_all_units) && !scene.hasField() && !scene.hasDialog()){
|
||||
selectedUnits.clear();
|
||||
commandBuildings.clear();
|
||||
for(var unit : player.team().data().units){
|
||||
if(unit.isCommandable()){
|
||||
selectedUnits.add(unit);
|
||||
if(commandMode && !scene.hasField() && !scene.hasDialog()){
|
||||
if(input.keyTap(Binding.select_all_units)){
|
||||
selectedUnits.clear();
|
||||
commandBuildings.clear();
|
||||
for(var unit : player.team().data().units){
|
||||
if(unit.isCommandable()){
|
||||
selectedUnits.add(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(commandMode && input.keyTap(Binding.select_all_unit_factories) && !scene.hasField() && !scene.hasDialog()){
|
||||
selectedUnits.clear();
|
||||
commandBuildings.clear();
|
||||
for(var build : player.team().data().buildings){
|
||||
if(build.block.commandable){
|
||||
commandBuildings.add(build);
|
||||
if(input.keyTap(Binding.select_all_unit_factories)){
|
||||
selectedUnits.clear();
|
||||
commandBuildings.clear();
|
||||
for(var build : player.team().data().buildings){
|
||||
if(build.block.commandable){
|
||||
commandBuildings.add(build);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < controlGroupBindings.length; i++){
|
||||
if(input.keyTap(controlGroupBindings[i])){
|
||||
|
||||
//create control group if it doesn't exist yet
|
||||
if(controlGroups[i] == null) controlGroups[i] = new IntSeq();
|
||||
|
||||
IntSeq group = controlGroups[i];
|
||||
boolean creating = input.keyDown(Binding.create_control_group);
|
||||
|
||||
//clear existing if making a new control group
|
||||
//if any of the control group edit buttons are pressed take the current selection
|
||||
if(creating){
|
||||
group.clear();
|
||||
|
||||
IntSeq selectedUnitIds = selectedUnits.mapInt(u -> u.id);
|
||||
if(Core.settings.getBool("distinctcontrolgroups", true)){
|
||||
for(IntSeq cg : controlGroups){
|
||||
if(cg != null){
|
||||
cg.removeAll(selectedUnitIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
group.addAll(selectedUnitIds);
|
||||
}
|
||||
|
||||
//remove invalid units
|
||||
for(int j = 0; j < group.size; j++){
|
||||
Unit u = Groups.unit.getByID(group.get(j));
|
||||
if(u == null || !u.isCommandable() || !u.isValid()){
|
||||
group.removeIndex(j);
|
||||
j --;
|
||||
}
|
||||
}
|
||||
|
||||
//replace the selected units with the current control group
|
||||
if(!group.isEmpty() && !creating){
|
||||
selectedUnits.clear();
|
||||
commandBuildings.clear();
|
||||
|
||||
group.each(id -> {
|
||||
var unit = Groups.unit.getByID(id);
|
||||
if(unit != null){
|
||||
selectedUnits.addAll(unit);
|
||||
}
|
||||
});
|
||||
|
||||
//double tap to center camera
|
||||
if(lastCtrlGroup == i && Time.timeSinceMillis(lastCtrlGroupSelectMillis) < 400){
|
||||
float totalX = 0, totalY = 0;
|
||||
for(Unit unit : selectedUnits){
|
||||
totalX += unit.x;
|
||||
totalY += unit.y;
|
||||
}
|
||||
panning = true;
|
||||
Core.camera.position.set(totalX / selectedUnits.size, totalY / selectedUnits.size);
|
||||
}
|
||||
lastCtrlGroup = i;
|
||||
lastCtrlGroupSelectMillis = Time.millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,18 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
final static int maxLength = 100;
|
||||
final static Rect r1 = new Rect(), r2 = new Rect();
|
||||
final static Seq<Unit> tmpUnits = new Seq<>(false);
|
||||
final static Binding[] controlGroupBindings = {
|
||||
Binding.block_select_01,
|
||||
Binding.block_select_02,
|
||||
Binding.block_select_03,
|
||||
Binding.block_select_04,
|
||||
Binding.block_select_05,
|
||||
Binding.block_select_06,
|
||||
Binding.block_select_07,
|
||||
Binding.block_select_08,
|
||||
Binding.block_select_09,
|
||||
Binding.block_select_10
|
||||
};
|
||||
|
||||
/** If true, there is a cutscene currently occurring in logic. */
|
||||
public boolean logicCutscene;
|
||||
@@ -87,6 +99,8 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
public boolean commandRect = false;
|
||||
public boolean tappedOne = false;
|
||||
public float commandRectX, commandRectY;
|
||||
/** Groups of units saved to different hotkeys */
|
||||
public IntSeq[] controlGroups = new IntSeq[controlGroupBindings.length];
|
||||
|
||||
private Seq<BuildPlan> plansOut = new Seq<>(BuildPlan.class);
|
||||
private QuadTree<BuildPlan> playerPlanTree = new QuadTree<>(new Rect());
|
||||
@@ -124,6 +138,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
Events.on(ResetEvent.class, e -> {
|
||||
logicCutscene = false;
|
||||
Arrays.fill(controlGroups, null);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user