Loop unit transfer command

This commit is contained in:
Anuken 2024-06-20 17:26:10 -04:00
parent b81553f490
commit 5b9d3029a5
9 changed files with 86 additions and 12 deletions

View File

@ -359,6 +359,7 @@ command.enterPayload = Enter Payload Block
command.loadUnits = Load Units
command.loadBlocks = Load Blocks
command.unloadPayload = Unload Payload
command.loopPayload = Loop Unit Transfer
stance.stop = Cancel Orders
stance.shoot = Stance: Shoot
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_unload_payload.name = Unit Command: Unload 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.schematic_select.name = Select Region

View File

@ -17,7 +17,7 @@ public class UnitCommand extends MappableContent{
@Deprecated
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). */
public final String icon;
@ -110,5 +110,10 @@ public class UnitCommand extends MappableContent{
drawTarget = true;
resetTarget = false;
}};
loopPayloadCommand = new UnitCommand("loopPayload", "resize", Binding.unit_command_loop_payload, null){{
switchToMove = false;
drawTarget = true;
resetTarget = false;
}};
}
}

View File

@ -20,11 +20,12 @@ public class CommandAI extends AIController{
protected static final Vec2 vecOut = new Vec2(), vecMovePos = new Vec2();
protected static final boolean[] noFound = {false};
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 @Nullable Vec2 targetPos;
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 int groupIndex = 0;
/** 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 boolean blockingUnit;
protected float timeSpentBlocked;
protected int transferState = transferStateNone;
/** Stance, usually related to firing mode. */
public UnitStance stance = UnitStance.shoot;
@ -113,6 +115,13 @@ public class CommandAI extends AIController{
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(){
if(!net.client() && unit instanceof Payloadc pay){
@ -123,10 +132,7 @@ public class CommandAI extends AIController{
//try to pick up what's under it
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));
if(target != null){
Call.pickedUnitPayload(unit, target);
}
tryPickupUnit(pay);
}
//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?
if(
(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;
}
@ -330,6 +337,46 @@ public class CommandAI extends AIController{
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;
targetPos = null;
@ -341,7 +388,7 @@ public class CommandAI extends AIController{
commandPosition(position);
}
if(prev != null && stance == UnitStance.patrol){
if(prev != null && (stance == UnitStance.patrol || command == UnitCommand.loopPayloadCommand)){
commandQueue.add(prev.cpy());
}

View File

@ -147,7 +147,8 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
Unit u = payload.unit;
//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;
}

View File

@ -60,6 +60,7 @@ public enum Binding implements KeyBind{
unit_command_load_units(KeyCode.unset),
unit_command_load_blocks(KeyCode.unset),
unit_command_unload_payload(KeyCode.unset),
unit_command_loop_payload(KeyCode.unset),
category_prev(KeyCode.comma, "blocks"),
category_next(KeyCode.period),

View File

@ -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){

View File

@ -246,7 +246,7 @@ public class TypeIO{
//this is irrelevant.
static final WeaponMount[] noMounts = {};
public static WeaponMount[] readMounts(Reads read){
read.skip(read.b() * (1 + 4 + 4));
@ -581,7 +581,7 @@ public class TypeIO{
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){
ai.commandQueue.clear();
int length = read.ub();

View File

@ -853,7 +853,7 @@ public class UnitType extends UnlockableContent implements Senseable{
cmds.add(UnitCommand.mineCommand);
}
if(example instanceof Payloadc){
cmds.addAll(UnitCommand.loadUnitsCommand, UnitCommand.loadBlocksCommand, UnitCommand.unloadPayloadCommand);
cmds.addAll(UnitCommand.loadUnitsCommand, UnitCommand.loadBlocksCommand, UnitCommand.unloadPayloadCommand, UnitCommand.loopPayloadCommand);
}
}

View File

@ -529,6 +529,10 @@ public class PlacementFragment{
if(stances.size > 1){
u.row();
if(commands.size > 1){
u.add(new Image(Tex.whiteui)).height(3f).color(Pal.gray).pad(7f).growX().row();
}
u.table(coms -> {
coms.left();
int scol = 0;