Loop unit transfer command
This commit is contained in:
@@ -359,6 +359,7 @@ command.enterPayload = Enter Payload Block
|
|||||||
command.loadUnits = Load Units
|
command.loadUnits = Load Units
|
||||||
command.loadBlocks = Load Blocks
|
command.loadBlocks = Load Blocks
|
||||||
command.unloadPayload = Unload Payload
|
command.unloadPayload = Unload Payload
|
||||||
|
command.loopPayload = Loop Unit Transfer
|
||||||
stance.stop = Cancel Orders
|
stance.stop = Cancel Orders
|
||||||
stance.shoot = Stance: Shoot
|
stance.shoot = Stance: Shoot
|
||||||
stance.holdfire = Stance: Hold Fire
|
stance.holdfire = Stance: Hold Fire
|
||||||
@@ -1274,6 +1275,7 @@ keybind.unit_command_load_units.name = Unit Command: Load Units
|
|||||||
keybind.unit_command_load_blocks.name = Unit Command: Load Blocks
|
keybind.unit_command_load_blocks.name = Unit Command: Load Blocks
|
||||||
keybind.unit_command_unload_payload.name = Unit Command: Unload Payload
|
keybind.unit_command_unload_payload.name = Unit Command: Unload Payload
|
||||||
keybind.unit_command_enter_payload.name = Unit Command: Enter Payload
|
keybind.unit_command_enter_payload.name = Unit Command: Enter Payload
|
||||||
|
keybind.unit_command_loop_payload.name = Unit Command: Loop Unit Transfer
|
||||||
|
|
||||||
keybind.rebuild_select.name = Rebuild Region
|
keybind.rebuild_select.name = Rebuild Region
|
||||||
keybind.schematic_select.name = Select Region
|
keybind.schematic_select.name = Select Region
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class UnitCommand extends MappableContent{
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static final Seq<UnitCommand> all = new Seq<>();
|
public static final Seq<UnitCommand> all = new Seq<>();
|
||||||
|
|
||||||
public static UnitCommand moveCommand, repairCommand, rebuildCommand, assistCommand, mineCommand, boostCommand, enterPayloadCommand, loadUnitsCommand, loadBlocksCommand, unloadPayloadCommand;
|
public static UnitCommand moveCommand, repairCommand, rebuildCommand, assistCommand, mineCommand, boostCommand, enterPayloadCommand, loadUnitsCommand, loadBlocksCommand, unloadPayloadCommand, loopPayloadCommand;
|
||||||
|
|
||||||
/** Name of UI icon (from Icon class). */
|
/** Name of UI icon (from Icon class). */
|
||||||
public final String icon;
|
public final String icon;
|
||||||
@@ -110,5 +110,10 @@ public class UnitCommand extends MappableContent{
|
|||||||
drawTarget = true;
|
drawTarget = true;
|
||||||
resetTarget = false;
|
resetTarget = false;
|
||||||
}};
|
}};
|
||||||
|
loopPayloadCommand = new UnitCommand("loopPayload", "resize", Binding.unit_command_loop_payload, null){{
|
||||||
|
switchToMove = false;
|
||||||
|
drawTarget = true;
|
||||||
|
resetTarget = false;
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ public class CommandAI extends AIController{
|
|||||||
protected static final Vec2 vecOut = new Vec2(), vecMovePos = new Vec2();
|
protected static final Vec2 vecOut = new Vec2(), vecMovePos = new Vec2();
|
||||||
protected static final boolean[] noFound = {false};
|
protected static final boolean[] noFound = {false};
|
||||||
protected static final UnitPayload tmpPayload = new UnitPayload(null);
|
protected static final UnitPayload tmpPayload = new UnitPayload(null);
|
||||||
|
protected static final int transferStateNone = 0, transferStateLoad = 1, transferStateUnload = 2;
|
||||||
|
|
||||||
public Seq<Position> commandQueue = new Seq<>(5);
|
public Seq<Position> commandQueue = new Seq<>(5);
|
||||||
public @Nullable Vec2 targetPos;
|
public @Nullable Vec2 targetPos;
|
||||||
public @Nullable Teamc attackTarget;
|
public @Nullable Teamc attackTarget;
|
||||||
/** Group of units that were all commanded to reach the same point.. */
|
/** Group of units that were all commanded to reach the same point. */
|
||||||
public @Nullable UnitGroup group;
|
public @Nullable UnitGroup group;
|
||||||
public int groupIndex = 0;
|
public int groupIndex = 0;
|
||||||
/** All encountered unreachable buildings of this AI. Why a sequence? Because contains() is very rarely called on it. */
|
/** All encountered unreachable buildings of this AI. Why a sequence? Because contains() is very rarely called on it. */
|
||||||
@@ -36,6 +37,7 @@ public class CommandAI extends AIController{
|
|||||||
protected Vec2 lastTargetPos;
|
protected Vec2 lastTargetPos;
|
||||||
protected boolean blockingUnit;
|
protected boolean blockingUnit;
|
||||||
protected float timeSpentBlocked;
|
protected float timeSpentBlocked;
|
||||||
|
protected int transferState = transferStateNone;
|
||||||
|
|
||||||
/** Stance, usually related to firing mode. */
|
/** Stance, usually related to firing mode. */
|
||||||
public UnitStance stance = UnitStance.shoot;
|
public UnitStance stance = UnitStance.shoot;
|
||||||
@@ -113,6 +115,13 @@ public class CommandAI extends AIController{
|
|||||||
attackTarget = null;
|
attackTarget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tryPickupUnit(Payloadc pay){
|
||||||
|
Unit target = Units.closest(unit.team, unit.x, unit.y, unit.type.hitSize * 2f, u -> u.isAI() && u != unit && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize));
|
||||||
|
if(target != null){
|
||||||
|
Call.pickedUnitPayload(unit, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void defaultBehavior(){
|
public void defaultBehavior(){
|
||||||
|
|
||||||
if(!net.client() && unit instanceof Payloadc pay){
|
if(!net.client() && unit instanceof Payloadc pay){
|
||||||
@@ -123,10 +132,7 @@ public class CommandAI extends AIController{
|
|||||||
|
|
||||||
//try to pick up what's under it
|
//try to pick up what's under it
|
||||||
if(command == UnitCommand.loadUnitsCommand){
|
if(command == UnitCommand.loadUnitsCommand){
|
||||||
Unit target = Units.closest(unit.team, unit.x, unit.y, unit.type.hitSize * 2f, u -> u.isAI() && u != unit && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize));
|
tryPickupUnit(pay);
|
||||||
if(target != null){
|
|
||||||
Call.pickedUnitPayload(unit, target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to pick up a block
|
//try to pick up a block
|
||||||
@@ -223,7 +229,8 @@ public class CommandAI extends AIController{
|
|||||||
//TODO: should the unit stop when it finds a target?
|
//TODO: should the unit stop when it finds a target?
|
||||||
if(
|
if(
|
||||||
(stance == UnitStance.patrol && target != null && unit.within(target, unit.type.range - 2f) && !unit.type.circleTarget) ||
|
(stance == UnitStance.patrol && target != null && unit.within(target, unit.type.range - 2f) && !unit.type.circleTarget) ||
|
||||||
(command == UnitCommand.enterPayloadCommand && unit.within(targetPos, 4f) || (targetBuild != null && unit.within(targetBuild, targetBuild.block.size * tilesize/2f * 0.9f)))
|
(command == UnitCommand.enterPayloadCommand && unit.within(targetPos, 4f) || (targetBuild != null && unit.within(targetBuild, targetBuild.block.size * tilesize/2f * 0.9f))) ||
|
||||||
|
(command == UnitCommand.loopPayloadCommand && unit.within(targetPos, 10f))
|
||||||
){
|
){
|
||||||
move = false;
|
move = false;
|
||||||
}
|
}
|
||||||
@@ -330,6 +337,46 @@ public class CommandAI extends AIController{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!net.client() && command == UnitCommand.loopPayloadCommand && unit instanceof Payloadc pay){
|
||||||
|
|
||||||
|
if(transferState == transferStateNone){
|
||||||
|
transferState = pay.hasPayload() ? transferStateUnload : transferStateLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(transferState == transferStateUnload){
|
||||||
|
//drop until there's a failure
|
||||||
|
int prev = -1;
|
||||||
|
while(pay.hasPayload() && prev != pay.payloads().size){
|
||||||
|
prev = pay.payloads().size;
|
||||||
|
Call.payloadDropped(unit, unit.x, unit.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//wait for everything to unload before running code below
|
||||||
|
if(pay.hasPayload()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}else if(transferState == transferStateLoad){
|
||||||
|
//pick up units until there's a failure
|
||||||
|
int prev = -1;
|
||||||
|
while(prev != pay.payloads().size){
|
||||||
|
prev = pay.payloads().size;
|
||||||
|
tryPickupUnit(pay);
|
||||||
|
}
|
||||||
|
|
||||||
|
//wait to load things before running code below
|
||||||
|
if(!pay.hasPayload()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//it will never finish
|
||||||
|
if(commandQueue.size == 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transferState = transferStateNone;
|
||||||
|
|
||||||
Vec2 prev = targetPos;
|
Vec2 prev = targetPos;
|
||||||
targetPos = null;
|
targetPos = null;
|
||||||
|
|
||||||
@@ -341,7 +388,7 @@ public class CommandAI extends AIController{
|
|||||||
commandPosition(position);
|
commandPosition(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prev != null && stance == UnitStance.patrol){
|
if(prev != null && (stance == UnitStance.patrol || command == UnitCommand.loopPayloadCommand)){
|
||||||
commandQueue.add(prev.cpy());
|
commandQueue.add(prev.cpy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,8 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
|||||||
Unit u = payload.unit;
|
Unit u = payload.unit;
|
||||||
|
|
||||||
//can't drop ground units
|
//can't drop ground units
|
||||||
if(!u.canPass(tileX(), tileY()) || Units.count(x, y, u.physicSize(), o -> o.isGrounded()) > 1){
|
//allow stacking for small units for now - otherwise, unit transfer would get annoying
|
||||||
|
if(!u.canPass(tileX(), tileY()) || Units.count(x, y, u.physicSize(), o -> o.isGrounded() && o.hitSize > 14f) > 1){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ public enum Binding implements KeyBind{
|
|||||||
unit_command_load_units(KeyCode.unset),
|
unit_command_load_units(KeyCode.unset),
|
||||||
unit_command_load_blocks(KeyCode.unset),
|
unit_command_load_blocks(KeyCode.unset),
|
||||||
unit_command_unload_payload(KeyCode.unset),
|
unit_command_unload_payload(KeyCode.unset),
|
||||||
|
unit_command_loop_payload(KeyCode.unset),
|
||||||
|
|
||||||
category_prev(KeyCode.comma, "blocks"),
|
category_prev(KeyCode.comma, "blocks"),
|
||||||
category_next(KeyCode.period),
|
category_next(KeyCode.period),
|
||||||
|
|||||||
@@ -1088,6 +1088,20 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ai.targetPos != null && ai.currentCommand() == UnitCommand.loopPayloadCommand && unit instanceof Payloadc pay){
|
||||||
|
Draw.color(Pal.accent, 0.4f + Mathf.absin(5f, 0.5f));
|
||||||
|
TextureRegion region = pay.hasPayload() ? Icon.download.getRegion() : Icon.upload.getRegion();
|
||||||
|
float offset = 11f;
|
||||||
|
float size = 8f;
|
||||||
|
Draw.rect(region, ai.targetPos.x, ai.targetPos.y + offset, size, size / region.ratio());
|
||||||
|
|
||||||
|
if(ai.commandQueue.size > 0){
|
||||||
|
region = !pay.hasPayload() ? Icon.download.getRegion() : Icon.upload.getRegion();
|
||||||
|
Draw.rect(region, ai.commandQueue.first().getX(), ai.commandQueue.first().getY() + offset, size, size / region.ratio());
|
||||||
|
}
|
||||||
|
Draw.color();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var commandBuild : commandBuildings){
|
for(var commandBuild : commandBuildings){
|
||||||
|
|||||||
@@ -581,7 +581,7 @@ public class TypeIO{
|
|||||||
if(ai.command == null) ai.command = UnitCommand.moveCommand;
|
if(ai.command == null) ai.command = UnitCommand.moveCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
//command queue only in type 7
|
//command queue only in type 7/8
|
||||||
if(type == 7 || type == 8){
|
if(type == 7 || type == 8){
|
||||||
ai.commandQueue.clear();
|
ai.commandQueue.clear();
|
||||||
int length = read.ub();
|
int length = read.ub();
|
||||||
|
|||||||
@@ -853,7 +853,7 @@ public class UnitType extends UnlockableContent implements Senseable{
|
|||||||
cmds.add(UnitCommand.mineCommand);
|
cmds.add(UnitCommand.mineCommand);
|
||||||
}
|
}
|
||||||
if(example instanceof Payloadc){
|
if(example instanceof Payloadc){
|
||||||
cmds.addAll(UnitCommand.loadUnitsCommand, UnitCommand.loadBlocksCommand, UnitCommand.unloadPayloadCommand);
|
cmds.addAll(UnitCommand.loadUnitsCommand, UnitCommand.loadBlocksCommand, UnitCommand.unloadPayloadCommand, UnitCommand.loopPayloadCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -529,6 +529,10 @@ public class PlacementFragment{
|
|||||||
if(stances.size > 1){
|
if(stances.size > 1){
|
||||||
u.row();
|
u.row();
|
||||||
|
|
||||||
|
if(commands.size > 1){
|
||||||
|
u.add(new Image(Tex.whiteui)).height(3f).color(Pal.gray).pad(7f).growX().row();
|
||||||
|
}
|
||||||
|
|
||||||
u.table(coms -> {
|
u.table(coms -> {
|
||||||
coms.left();
|
coms.left();
|
||||||
int scol = 0;
|
int scol = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user