diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index 2aec41a15d..df856d6688 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -20,7 +20,7 @@ public class LogicAI extends AIController{ public LUnitControl control = LUnitControl.stop; public float moveX, moveY, moveRad; - public float itemTimer, controlTimer = logicControlTimeout, targetTimer; + public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer; public Building controller; public BuildPlan plan = new BuildPlan(); @@ -43,9 +43,8 @@ public class LogicAI extends AIController{ @Override protected void updateMovement(){ - if(itemTimer > 0){ - itemTimer -= Time.delta; - } + if(itemTimer > 0) itemTimer -= Time.delta; + if(payTimer > 0) payTimer -= Time.delta; if(targetTimer > 0f){ targetTimer -= Time.delta; @@ -67,7 +66,7 @@ public class LogicAI extends AIController{ moveTo(Tmp.v1.set(moveX, moveY), 1f, 30f); } case approach -> { - moveTo(Tmp.v1.set(moveX, moveY), moveRad, 1f); + moveTo(Tmp.v1.set(moveX, moveY), moveRad - 8f, 8f); } case pathfind -> { Building core = unit.closestEnemyCore(); diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index eec8683b8a..a5327cd6a3 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -287,7 +287,7 @@ public class Blocks implements ContentList{ salt = new Floor("salt"){{ variants = 0; - attributes.set(Attribute.water, -0.25f); + attributes.set(Attribute.water, -0.3f); attributes.set(Attribute.oil, 0.3f); }}; @@ -718,7 +718,7 @@ public class Blocks implements ContentList{ size = 2; hasPower = hasItems = hasLiquids = true; - consumes.liquid(Liquids.oil, 0.09f); + consumes.liquid(Liquids.oil, 0.1f); consumes.power(0.5f); }}; diff --git a/core/src/mindustry/entities/comp/BuilderComp.java b/core/src/mindustry/entities/comp/BuilderComp.java index 9d4d4c1bb9..ccc83e87d8 100644 --- a/core/src/mindustry/entities/comp/BuilderComp.java +++ b/core/src/mindustry/entities/comp/BuilderComp.java @@ -208,7 +208,7 @@ abstract class BuilderComp implements Unitc{ BuildPlan plan = buildPlan(); Tile tile = world.tile(plan.x, plan.y); - if((dst(tile) > buildingRange && !state.isEditor()) || !plan.initialized){ + if(dst(tile) > buildingRange && !state.isEditor()){ return; } diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 69295a9e0d..5a285aca10 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -46,7 +46,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, static final Seq tempTiles = new Seq<>(); static int sleepingEntities = 0; - @Import float x, y, health; + @Import float x, y, health, maxHealth; @Import Team team; transient Tile tile; @@ -1224,7 +1224,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case y -> y; case team -> team.id; case health -> health; - case maxHealth -> maxHealth(); + case maxHealth -> maxHealth; case efficiency -> efficiency(); case rotation -> rotation; case totalItems -> items == null ? 0 : items.total(); @@ -1238,6 +1238,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case powerNetStored -> power == null ? 0 : power.graph.getLastPowerStored(); case powerNetCapacity -> power == null ? 0 : power.graph.getLastCapacity(); case enabled -> enabled ? 1 : 0; + case payloadCount -> getPayload() != null ? 1 : 0; default -> 0; }; } @@ -1248,6 +1249,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, case type -> block; case firstItem -> items == null ? null : items.first(); case config -> block.configurations.containsKey(Item.class) || block.configurations.containsKey(Liquid.class) ? config() : null; + case payloadType -> getPayload() instanceof UnitPayload p1 ? p1.unit.type() : getPayload() instanceof BlockPayload p2 ? p2.block() : null; default -> noSensed; }; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 3e912fce88..c79a6557e0 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -23,6 +23,7 @@ import mindustry.type.*; import mindustry.ui.*; import mindustry.world.*; import mindustry.world.blocks.environment.*; +import mindustry.world.blocks.payloads.*; import static mindustry.Vars.*; @@ -96,6 +97,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case shootX -> aimX(); case shootY -> aimY(); case flag -> flag; + case payloadCount -> self() instanceof Payloadc pay ? pay.payloads().size : 0; default -> 0; }; } @@ -106,6 +108,10 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case type -> type; case name -> controller instanceof Player p ? p.name : null; case firstItem -> stack().amount == 0 ? null : item(); + case payloadType -> self() instanceof Payloadc pay ? + (pay.payloads().isEmpty() ? null : + pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type() : + pay.payloads().peek() instanceof BlockPayload p2 ? p2.block() : null) : null; default -> noSensed; }; diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 868f9a254c..1b6e92caf2 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -159,7 +159,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ if(target.isAI() && target.isGrounded() && pay.canPickup(target) && target.within(unit, unit.type().hitSize * 2f + target.type().hitSize * 2f)){ - Call.pickedUnitPayload(player, target); + Call.pickedUnitPayload(unit, target); } } @@ -174,57 +174,49 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ && unit.within(tile, tilesize * tile.block.size * 1.2f + tilesize * 5f)){ //pick up block directly if(tile.block.buildVisibility != BuildVisibility.hidden && tile.canPickup() && pay.canPickup(tile)){ - Call.pickedBlockPayload(player, tile, true); + Call.pickedBlockPayload(unit, tile, true); }else{ //pick up block payload Payload current = tile.getPayload(); if(current != null && pay.canPickupPayload(current)){ - Call.pickedBlockPayload(player, tile, false); + Call.pickedBlockPayload(unit, tile, false); } } } } @Remote(targets = Loc.server, called = Loc.server) - public static void pickedUnitPayload(Player player, Unit target){ - if(player == null || target == null || !(player.unit() instanceof Payloadc)){ - if(target != null){ - target.remove(); - } - return; + public static void pickedUnitPayload(Unit unit, Unit target){ + if(target != null && unit instanceof Payloadc pay){ + pay.pickup(target); + }else if(target != null){ + target.remove(); } - - ((Payloadc)player.unit()).pickup(target); } @Remote(targets = Loc.server, called = Loc.server) - public static void pickedBlockPayload(Player player, Building tile, boolean onGround){ - if(player == null || tile == null || !(player.unit() instanceof Payloadc)){ - if(tile != null && onGround){ - Fx.unitPickup.at(tile); - tile.tile.remove(); - } - return; - } - - Unit unit = player.unit(); - Payloadc pay = (Payloadc)unit; - - if(onGround){ - if(tile.block.buildVisibility != BuildVisibility.hidden && tile.canPickup() && pay.canPickup(tile)){ - pay.pickup(tile); - }else{ - Fx.unitPickup.at(tile); - tile.tile.remove(); - } - }else{ - Payload current = tile.getPayload(); - if(current != null && pay.canPickupPayload(current)){ - Payload taken = tile.takePayload(); - if(taken != null){ - pay.addPayload(taken); + public static void pickedBlockPayload(Unit unit, Building tile, boolean onGround){ + if(tile != null && unit instanceof Payloadc pay){ + if(onGround){ + if(tile.block.buildVisibility != BuildVisibility.hidden && tile.canPickup() && pay.canPickup(tile)){ + pay.pickup(tile); + }else{ Fx.unitPickup.at(tile); + tile.tile.remove(); + } + }else{ + Payload current = tile.getPayload(); + if(current != null && pay.canPickupPayload(current)){ + Payload taken = tile.takePayload(); + if(taken != null){ + pay.addPayload(taken); + Fx.unitPickup.at(tile); + } } } + + }else if(tile != null && onGround){ + Fx.unitPickup.at(tile); + tile.tile.remove(); } } @@ -238,19 +230,17 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ Tmp.v1.set(x, y).sub(pay).limit(tilesize * 4f).add(pay); float cx = Tmp.v1.x, cy = Tmp.v1.y; - Call.payloadDropped(player, cx, cy); + Call.payloadDropped(player.unit(), cx, cy); } @Remote(called = Loc.server, targets = Loc.server) - public static void payloadDropped(Player player, float x, float y){ - if(player == null) return; - - Payloadc pay = (Payloadc)player.unit(); - - float prevx = pay.x(), prevy = pay.y(); - pay.set(x, y); - pay.dropLastPayload(); - pay.set(prevx, prevy); + public static void payloadDropped(Unit unit, float x, float y){ + if(unit instanceof Payloadc pay){ + float prevx = pay.x(), prevy = pay.y(); + pay.set(x, y); + pay.dropLastPayload(); + pay.set(prevx, prevy); + } } @Remote(targets = Loc.client, called = Loc.server) diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index 1ff9e808a5..5dc881a778 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -30,6 +30,8 @@ public enum LAccess{ flag, name, config, + payloadCount, + payloadType, //values with parameters are considered controllable enabled("to"), //"to" is standard for single parameter access diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index f0752b49df..d1db916be1 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -15,6 +15,7 @@ import mindustry.world.*; import mindustry.world.blocks.logic.LogicDisplay.*; import mindustry.world.blocks.logic.MemoryBlock.*; import mindustry.world.blocks.logic.MessageBlock.*; +import mindustry.world.blocks.payloads.*; import mindustry.world.meta.*; import static mindustry.Vars.*; @@ -370,13 +371,47 @@ public class LExecutor{ miner.mineTile(miner.validMine(tile) ? tile : null); } } + case payDrop -> { + if(ai.payTimer > 0) return; + + if(unit instanceof Payloadc pay && pay.hasPayload()){ + Call.payloadDropped(unit, unit.x, unit.y); + ai.payTimer = LogicAI.transferDelay; + } + } + case payTake -> { + if(ai.payTimer > 0) return; + + if(unit instanceof Payloadc pay){ + //units + if(exec.bool(p1)){ + Unit result = Units.closest(unit.team, unit.x, unit.y, unit.type().hitSize * 2f, u -> u.isAI() && u.isGrounded() && pay.canPickup(u) && u.within(unit, u.hitSize + unit.hitSize * 1.2f)); + + Call.pickedUnitPayload(unit, result); + }else{ //buildings + Building tile = world.buildWorld(unit.x, unit.y); + + //TODO copy pasted code + if(tile != null && tile.team == unit.team){ + if(tile.block.buildVisibility != BuildVisibility.hidden && tile.canPickup() && pay.canPickup(tile)){ + Call.pickedBlockPayload(unit, tile, true); + }else{ //pick up block payload + Payload current = tile.getPayload(); + if(current != null && pay.canPickupPayload(current)){ + Call.pickedBlockPayload(unit, tile, false); + } + } + } + } + ai.payTimer = LogicAI.transferDelay; + } + } case build -> { if(unit instanceof Builderc builder && exec.obj(p3) instanceof Block block){ int x = world.toTile(exec.numf(p1)), y = world.toTile(exec.numf(p2)); int rot = exec.numi(p4); - //reset state if: - // + //reset state of last request when necessary if(ai.plan.x != x || ai.plan.y != y || ai.plan.block != block || builder.plans().isEmpty()){ ai.plan.progress = 0; ai.plan.initialized = false; diff --git a/core/src/mindustry/logic/LUnitControl.java b/core/src/mindustry/logic/LUnitControl.java index 2273fe0575..879578e59b 100644 --- a/core/src/mindustry/logic/LUnitControl.java +++ b/core/src/mindustry/logic/LUnitControl.java @@ -10,6 +10,8 @@ public enum LUnitControl{ targetp("unit", "shoot"), itemDrop("to", "amount"), itemTake("from", "item", "amount"), + payDrop, + payTake("takeUnits"), mine("x", "y"), flag("value"), build("x", "y", "block", "rotation"),