Allow commands/stances even when units do not have them in common
This commit is contained in:
@@ -363,7 +363,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
|
||||
for(int id : unitIds){
|
||||
Unit unit = Groups.unit.getByID(id);
|
||||
if(unit != null && unit.team == player.team() && unit.controller() instanceof CommandAI ai){
|
||||
if(unit != null && unit.team == player.team() && unit.controller() instanceof CommandAI ai && unit.type.allowCommand(unit, command)){
|
||||
boolean reset = command.resetTarget || ai.currentCommand().resetTarget;
|
||||
ai.command(command);
|
||||
if(reset){
|
||||
@@ -372,7 +372,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
}
|
||||
unit.lastCommanded = player.coloredName();
|
||||
|
||||
//make sure its stance is valid
|
||||
//make sure its current stance is valid with its current command
|
||||
stancesOut.clear();
|
||||
unit.type.getUnitStances(unit, stancesOut);
|
||||
if(stancesOut.size > 0 && !stancesOut.contains(ai.stance)){
|
||||
@@ -397,7 +397,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(unit != null && unit.team == player.team() && unit.controller() instanceof CommandAI ai){
|
||||
if(stance == UnitStance.stop){ //not a real stance, just cancels orders
|
||||
ai.clearCommands();
|
||||
}else{
|
||||
}else if(unit.type.allowStance(unit, stance)){
|
||||
ai.stance = stance;
|
||||
}
|
||||
unit.lastCommanded = player.coloredName();
|
||||
|
||||
@@ -44,6 +44,7 @@ import static mindustry.Vars.*;
|
||||
public class UnitType extends UnlockableContent implements Senseable{
|
||||
public static final float shadowTX = -12, shadowTY = -13;
|
||||
private static final Vec2 legOffset = new Vec2();
|
||||
private static final Seq<UnitStance> tmpStances = new Seq<>();
|
||||
|
||||
/** Environmental flags that are *all* required for this unit to function. 0 = any environment */
|
||||
public int envRequired = 0;
|
||||
@@ -610,6 +611,17 @@ public class UnitType extends UnlockableContent implements Senseable{
|
||||
}
|
||||
}
|
||||
|
||||
public boolean allowStance(Unit unit, UnitStance stance){
|
||||
if(stance == UnitStance.stop) return true;
|
||||
tmpStances.clear();
|
||||
getUnitStances(unit, tmpStances);
|
||||
return tmpStances.contains(stance);
|
||||
}
|
||||
|
||||
public boolean allowCommand(Unit unit, UnitCommand command){
|
||||
return commands.contains(command);
|
||||
}
|
||||
|
||||
public void update(Unit unit){
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.ai.types.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.entities.*;
|
||||
@@ -460,24 +461,31 @@ public class PlacementFragment{
|
||||
commandTable.add(Core.bundle.get("commandmode.name")).fill().center().labelAlign(Align.center).row();
|
||||
commandTable.image().color(Pal.accent).growX().pad(20f).padTop(0f).padBottom(4f).row();
|
||||
commandTable.table(u -> {
|
||||
|
||||
Bits activeCommands = new Bits(content.unitCommands().size);
|
||||
Bits activeStances = new Bits(content.unitStances().size);
|
||||
|
||||
Bits availableCommands = new Bits(content.unitCommands().size);
|
||||
Bits availableStances = new Bits(content.unitStances().size);
|
||||
|
||||
u.left();
|
||||
int[] curCount = {0};
|
||||
UnitCommand[] currentCommand = {null};
|
||||
Bits usedCommands = new Bits(content.unitCommands().size);
|
||||
var commands = new Seq<UnitCommand>();
|
||||
|
||||
UnitStance[] currentStance = {null};
|
||||
Bits usedStances = new Bits(content.unitStances().size);
|
||||
var stances = new Seq<UnitStance>();
|
||||
|
||||
var stancesOut = new Seq<UnitStance>();
|
||||
|
||||
rebuildCommand = () -> {
|
||||
u.clearChildren();
|
||||
var units = control.input.selectedUnits;
|
||||
if(units.size > 0){
|
||||
usedCommands.clear();
|
||||
usedStances.clear();
|
||||
commands.clear();
|
||||
stances.clear();
|
||||
|
||||
boolean firstCommand = false, firstStance = false;
|
||||
int[] counts = new int[content.units().size];
|
||||
|
||||
for(var unit : units){
|
||||
@@ -486,12 +494,11 @@ public class PlacementFragment{
|
||||
stancesOut.clear();
|
||||
unit.type.getUnitStances(unit, stancesOut);
|
||||
|
||||
if(!firstStance){
|
||||
stances.add(stancesOut);
|
||||
firstStance = true;
|
||||
}else{
|
||||
//remove commands that this next unit type doesn't have
|
||||
stances.removeAll(st -> !stancesOut.contains(st));
|
||||
for(var stance : stancesOut){
|
||||
if(!usedStances.get(stance.id)){
|
||||
stances.add(stance);
|
||||
usedStances.set(stance.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,12 +536,11 @@ public class PlacementFragment{
|
||||
unitlist.row();
|
||||
}
|
||||
|
||||
if(!firstCommand){
|
||||
commands.add(type.commands);
|
||||
firstCommand = true;
|
||||
}else{
|
||||
//remove commands that this next unit type doesn't have
|
||||
commands.removeAll(com -> !type.commands.contains(com));
|
||||
for(var command : type.commands){
|
||||
if(!usedCommands.get(command.id)){
|
||||
commands.add(command);
|
||||
usedCommands.set(command.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,8 +554,8 @@ public class PlacementFragment{
|
||||
int scol = 0;
|
||||
for(var command : commands){
|
||||
coms.button(Icon.icons.get(command.icon, Icon.cancel), Styles.clearNoneTogglei, () -> {
|
||||
Call.setUnitCommand(player, units.mapInt(un -> un.id).toArray(), command);
|
||||
}).checked(i -> currentCommand[0] == command).size(50f).tooltip(command.localized(), true);
|
||||
Call.setUnitCommand(player, units.mapInt(un -> un.id, un -> un.type.allowCommand(un, command)).toArray(), command);
|
||||
}).checked(i -> activeCommands.get(command.id)).size(50f).tooltip(command.localized(), true);
|
||||
|
||||
if(++scol % 6 == 0) coms.row();
|
||||
}
|
||||
@@ -571,8 +577,8 @@ public class PlacementFragment{
|
||||
for(var stance : stances){
|
||||
|
||||
coms.button(stance.getIcon(), Styles.clearNoneTogglei, () -> {
|
||||
Call.setUnitStance(player, units.mapInt(un -> un.id).toArray(), stance);
|
||||
}).checked(i -> currentStance[0] == stance).size(50f).tooltip(stance.localized(), true);
|
||||
Call.setUnitStance(player, units.mapInt(un -> un.id, un -> un.type.allowStance(un, stance)).toArray(), stance);
|
||||
}).checked(i -> activeStances.get(stance.id)).size(50f).tooltip(stance.localized(), true);
|
||||
|
||||
if(++scol % 6 == 0) coms.row();
|
||||
}
|
||||
@@ -585,58 +591,50 @@ public class PlacementFragment{
|
||||
|
||||
u.update(() -> {
|
||||
{
|
||||
boolean hadCommand = false, hadStance = false;
|
||||
UnitCommand shareCommand = null;
|
||||
UnitStance shareStance = null;
|
||||
activeCommands.clear();
|
||||
activeStances.clear();
|
||||
availableCommands.clear();
|
||||
availableStances.clear();
|
||||
|
||||
//find the command that all units have, or null if they do not share one
|
||||
for(var unit : control.input.selectedUnits){
|
||||
if(unit.isCommandable()){
|
||||
var nextCommand = unit.command().command;
|
||||
if(unit.controller() instanceof CommandAI cmd){
|
||||
activeCommands.set(cmd.command.id);
|
||||
activeStances.set(cmd.stance.id);
|
||||
|
||||
if(hadCommand){
|
||||
if(shareCommand != nextCommand){
|
||||
shareCommand = null;
|
||||
}
|
||||
}else{
|
||||
shareCommand = nextCommand;
|
||||
hadCommand = true;
|
||||
for(var command : unit.type.commands){
|
||||
availableCommands.set(command.id);
|
||||
}
|
||||
|
||||
var nextStance = unit.command().stance;
|
||||
stancesOut.clear();
|
||||
unit.type.getUnitStances(unit, stancesOut);
|
||||
|
||||
if(hadStance){
|
||||
if(shareStance != nextStance){
|
||||
shareStance = null;
|
||||
}
|
||||
}else{
|
||||
shareStance = nextStance;
|
||||
hadStance = true;
|
||||
for(var stance : stancesOut){
|
||||
availableStances.set(stance.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int size = control.input.selectedUnits.size;
|
||||
if(curCount[0] != size || (currentCommand[0] != shareCommand && shareCommand != null && currentCommand[0] != null && (currentCommand[0].refreshOnSelect || shareCommand.refreshOnSelect))){
|
||||
if(curCount[0] != size || !usedCommands.equals(availableCommands) || !usedStances.equals(availableStances)){
|
||||
if(!(curCount[0] + size == 0)){
|
||||
rebuildCommand.run();
|
||||
}
|
||||
curCount[0] = size;
|
||||
rebuildCommand.run();
|
||||
}
|
||||
|
||||
currentCommand[0] = shareCommand;
|
||||
currentStance[0] = shareStance;
|
||||
|
||||
//not a huge fan of running input logic here, but it's convenient as the stance arrays are all here...
|
||||
for(UnitStance stance : stances){
|
||||
//first stance must always be the stop stance
|
||||
if(stance.keybind != null && Core.input.keyTap(stance.keybind)){
|
||||
Call.setUnitStance(player, control.input.selectedUnits.mapInt(un -> un.id).toArray(), stance);
|
||||
Call.setUnitStance(player, control.input.selectedUnits.mapInt(un -> un.id, un -> un.type.allowStance(un, stance)).toArray(), stance);
|
||||
}
|
||||
}
|
||||
|
||||
for(UnitCommand command : commands){
|
||||
//first stance must always be the stop stance
|
||||
if(command.keybind != null && Core.input.keyTap(command.keybind)){
|
||||
Call.setUnitCommand(player, control.input.selectedUnits.mapInt(un -> un.id).toArray(), command);
|
||||
Call.setUnitCommand(player, control.input.selectedUnits.mapInt(un -> un.id, un -> un.type.allowCommand(un, command)).toArray(), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user