Allow controlling/selecting units with LogicAI

This commit is contained in:
Anuken
2025-04-21 14:23:01 -04:00
parent f1f610079d
commit 847ec1813e
6 changed files with 100 additions and 76 deletions
@@ -473,6 +473,12 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
return controller instanceof AIController;
}
/** @return whether the unit *can* be commanded, even if its controller is not currently CommandAI. */
public boolean allowCommand(){
return controller instanceof CommandAI || (controller instanceof LogicAI && type.allowChangeCommands);
}
/** @return whether the unit has a CommandAI controller */
public boolean isCommandable(){
return controller instanceof CommandAI;
}
+2 -2
View File
@@ -288,14 +288,14 @@ public class DesktopInput extends InputHandler{
}
//validate commanding units
selectedUnits.removeAll(u -> !u.isCommandable() || !u.isValid() || u.team != player.team());
selectedUnits.removeAll(u -> !u.allowCommand() || !u.isValid() || u.team != player.team());
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()){
if(unit.allowCommand()){
selectedUnits.add(unit);
}
}
+21 -9
View File
@@ -261,8 +261,14 @@ 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()){
if(unit.controller() instanceof LogicAI){
//reset to commandAI if applicable
unit.resetController();
}
if(unit.controller() instanceof CommandAI ai){
//implicitly order it to move
if(ai.command == null || ai.command.switchToMove){
ai.command(UnitCommand.moveCommand);
@@ -300,6 +306,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
toAdd.add(unit);
}
}
}
//in the "final batch" of commands, assign formations based on EVERYTHING that was commanded.
if(finalBatch){
@@ -1093,19 +1100,22 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public void drawCommanded(boolean flying){
float lineLimit = 6.5f;
Color color = Pal.accent;
int sides = 6;
float alpha = 0.5f;
if(commandMode){
//happens sometimes
selectedUnits.removeAll(u -> !u.isCommandable());
selectedUnits.removeAll(u -> !u.allowCommand());
//draw command overlay UI
for(Unit unit : selectedUnits){
CommandAI ai = unit.command();
Position lastPos = ai.attackTarget != null ? ai.attackTarget : ai.targetPos;
Color color = unit.controller() instanceof LogicAI ? Team.malis.color : Pal.accent;
Position lastPos = null;
if(unit.controller() instanceof CommandAI ai){
lastPos = ai.attackTarget != null ? ai.attackTarget : ai.targetPos;
if(flying && ai.attackTarget != null && ai.currentCommand().drawTarget){
Drawf.target(ai.attackTarget.getX(), ai.attackTarget.getY(), 6f, Pal.remove);
@@ -1129,6 +1139,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
}
}
}
float rad = unit.hitSize / unitSelectRadScl + 1f;
@@ -1148,12 +1159,11 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
//Lines.poly(unit.x, unit.y, sides, rad + 1.5f);
Draw.reset();
if(lastPos == null){
lastPos = unit;
}
if(unit.controller() instanceof CommandAI ai){
//draw command queue
if(ai.currentCommand().drawTarget && ai.commandQueue.size > 0){
for(var next : ai.commandQueue){
@@ -1182,8 +1192,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Draw.color();
}
}
}
if(flying){
Color color = Pal.accent;
for(var commandBuild : commandBuildings){
if(commandBuild != null){
Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f);
@@ -1897,7 +1909,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
tmpUnits.clear();
float rad = 4f;
tree.intersect(x - rad/2f, y - rad/2f, rad, rad, tmpUnits);
return tmpUnits.min(u -> u.isCommandable(), u -> u.dst(x, y) - u.hitSize/2f);
return tmpUnits.min(u -> u.allowCommand(), u -> u.dst(x, y) - u.hitSize/2f);
}
public @Nullable Unit selectedEnemyUnit(float x, float y){
@@ -1919,7 +1931,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
tmpUnits.clear();
float rad = 4f;
tree.intersect(Tmp.r1.set(x - rad/2f, y - rad/2f, rad*2f + w, rad*2f + h).normalize(), tmpUnits);
tmpUnits.removeAll(u -> !u.isCommandable() || !predicate.get(u));
tmpUnits.removeAll(u -> !u.allowCommand() || !predicate.get(u));
return tmpUnits;
}
+1 -1
View File
@@ -770,7 +770,7 @@ public class MobileInput extends InputHandler implements GestureListener{
}
//validate commanding units
selectedUnits.removeAll(u -> !u.isCommandable() || !u.isValid() || u.team != player.team());
selectedUnits.removeAll(u -> !u.allowCommand() || !u.isValid() || u.team != player.team());
if(!commandMode){
commandBuildings.clear();
@@ -109,6 +109,13 @@ public class LandingPad extends Block{
addBar("cooldown", (LandingPadBuild entity) -> new Bar("bar.cooldown", Pal.lightOrange, () -> entity.cooldown));
}
@Override
public void setStats(){
super.setStats();
stats.add(Stat.cooldownTime, (cooldownTime+arrivalDuration)/60f, StatUnit.seconds);
}
@Override
public boolean outputsItems(){
return true;
@@ -41,8 +41,7 @@ public class DesktopLauncher extends ClientLauncher{
maximized = true;
width = 900;
height = 700;
//request 3.1, which has instancing
gl30Minor = 1;
gl30Minor = 2;
gl30 = true;
for(int i = 0; i < arg.length; i++){
if(arg[i].charAt(0) == '-'){