Allow controlling/selecting units with LogicAI
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) == '-'){
|
||||||
|
|||||||
Reference in New Issue
Block a user