mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-03-09 20:29:06 +07:00
Loop unit transfer command
This commit is contained in:
parent
b81553f490
commit
5b9d3029a5
@ -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
|
||||
|
@ -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;
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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){
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user