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 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(){ public boolean isCommandable(){
return controller instanceof CommandAI; return controller instanceof CommandAI;
} }
+2 -2
View File
@@ -288,14 +288,14 @@ public class DesktopInput extends InputHandler{
} }
//validate commanding units //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(commandMode && !scene.hasField() && !scene.hasDialog()){
if(input.keyTap(Binding.select_all_units)){ if(input.keyTap(Binding.select_all_units)){
selectedUnits.clear(); selectedUnits.clear();
commandBuildings.clear(); commandBuildings.clear();
for(var unit : player.team().data().units){ for(var unit : player.team().data().units){
if(unit.isCommandable()){ if(unit.allowCommand()){
selectedUnits.add(unit); selectedUnits.add(unit);
} }
} }
+21 -9
View File
@@ -261,8 +261,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
for(int id : unitIds){ for(int id : unitIds){
Unit unit = Groups.unit.getByID(id); 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 //implicitly order it to move
if(ai.command == null || ai.command.switchToMove){ if(ai.command == null || ai.command.switchToMove){
ai.command(UnitCommand.moveCommand); ai.command(UnitCommand.moveCommand);
@@ -300,6 +306,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
toAdd.add(unit); toAdd.add(unit);
} }
} }
}
//in the "final batch" of commands, assign formations based on EVERYTHING that was commanded. //in the "final batch" of commands, assign formations based on EVERYTHING that was commanded.
if(finalBatch){ if(finalBatch){
@@ -1093,19 +1100,22 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public void drawCommanded(boolean flying){ public void drawCommanded(boolean flying){
float lineLimit = 6.5f; float lineLimit = 6.5f;
Color color = Pal.accent;
int sides = 6; int sides = 6;
float alpha = 0.5f; float alpha = 0.5f;
if(commandMode){ if(commandMode){
//happens sometimes //happens sometimes
selectedUnits.removeAll(u -> !u.isCommandable()); selectedUnits.removeAll(u -> !u.allowCommand());
//draw command overlay UI //draw command overlay UI
for(Unit unit : selectedUnits){ for(Unit unit : selectedUnits){
CommandAI ai = unit.command(); Color color = unit.controller() instanceof LogicAI ? Team.malis.color : Pal.accent;
Position lastPos = ai.attackTarget != null ? ai.attackTarget : ai.targetPos;
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){ if(flying && ai.attackTarget != null && ai.currentCommand().drawTarget){
Drawf.target(ai.attackTarget.getX(), ai.attackTarget.getY(), 6f, Pal.remove); 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; 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); //Lines.poly(unit.x, unit.y, sides, rad + 1.5f);
Draw.reset(); Draw.reset();
if(lastPos == null){ if(lastPos == null){
lastPos = unit; lastPos = unit;
} }
if(unit.controller() instanceof CommandAI ai){
//draw command queue //draw command queue
if(ai.currentCommand().drawTarget && ai.commandQueue.size > 0){ if(ai.currentCommand().drawTarget && ai.commandQueue.size > 0){
for(var next : ai.commandQueue){ for(var next : ai.commandQueue){
@@ -1182,8 +1192,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
Draw.color(); Draw.color();
} }
} }
}
if(flying){ if(flying){
Color color = Pal.accent;
for(var commandBuild : commandBuildings){ for(var commandBuild : commandBuildings){
if(commandBuild != null){ if(commandBuild != null){
Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f); Drawf.square(commandBuild.x, commandBuild.y, commandBuild.hitSize() / 1.4f + 1f);
@@ -1897,7 +1909,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
tmpUnits.clear(); tmpUnits.clear();
float rad = 4f; float rad = 4f;
tree.intersect(x - rad/2f, y - rad/2f, rad, rad, tmpUnits); 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){ public @Nullable Unit selectedEnemyUnit(float x, float y){
@@ -1919,7 +1931,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
tmpUnits.clear(); tmpUnits.clear();
float rad = 4f; float rad = 4f;
tree.intersect(Tmp.r1.set(x - rad/2f, y - rad/2f, rad*2f + w, rad*2f + h).normalize(), tmpUnits); 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; return tmpUnits;
} }
+1 -1
View File
@@ -770,7 +770,7 @@ public class MobileInput extends InputHandler implements GestureListener{
} }
//validate commanding units //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){ if(!commandMode){
commandBuildings.clear(); commandBuildings.clear();
@@ -109,6 +109,13 @@ public class LandingPad extends Block{
addBar("cooldown", (LandingPadBuild entity) -> new Bar("bar.cooldown", Pal.lightOrange, () -> entity.cooldown)); 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 @Override
public boolean outputsItems(){ public boolean outputsItems(){
return true; return true;
@@ -41,8 +41,7 @@ public class DesktopLauncher extends ClientLauncher{
maximized = true; maximized = true;
width = 900; width = 900;
height = 700; height = 700;
//request 3.1, which has instancing gl30Minor = 2;
gl30Minor = 1;
gl30 = true; gl30 = true;
for(int i = 0; i < arg.length; i++){ for(int i = 0; i < arg.length; i++){
if(arg[i].charAt(0) == '-'){ if(arg[i].charAt(0) == '-'){