diff --git a/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java b/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java index 4d9ce94869..e0c32bc820 100644 --- a/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java +++ b/annotations/src/main/java/mindustry/annotations/entity/EntityIO.java @@ -229,7 +229,7 @@ public class EntityIO{ s(type.equals("boolean") ? "bool" : type.charAt(0) + "", field); }else if(instanceOf(type, "mindustry.ctype.Content") && !type.equals("mindustry.ai.UnitStance") && !type.equals("mindustry.ai.UnitCommand")){ if(write){ - s("s", field + ".id"); + s("s", field + " == null ? -1 : " + field + ".id"); }else{ st(field + "mindustry.Vars.content.getByID(mindustry.ctype.ContentType.$L, read.s())", BaseProcessor.simpleName(type).toLowerCase().replace("type", "")); } diff --git a/core/src/mindustry/core/NetClient.java b/core/src/mindustry/core/NetClient.java index fbbd502826..e38694fe5a 100644 --- a/core/src/mindustry/core/NetClient.java +++ b/core/src/mindustry/core/NetClient.java @@ -13,6 +13,7 @@ import arc.util.serialization.*; import arc.util.serialization.JsonValue.*; import mindustry.*; import mindustry.annotations.Annotations.*; +import mindustry.content.*; import mindustry.core.GameState.*; import mindustry.entities.*; import mindustry.game.EventType.*; @@ -699,7 +700,7 @@ public class NetClient implements ApplicationListener{ unit == null ? 0f : unit.vel.x, unit == null ? 0f : unit.vel.y, dead ? null : unit.mineTile, player.boosting, player.shooting, ui.chatfrag.shown(), control.input.isBuilding, - player.isBuilder() && unit != null ? unit.plans : null, + player.selectedBlock, player.selectedRotation, player.isBuilder() && unit != null ? unit.plans : null, Core.camera.position.x, Core.camera.position.y, Core.camera.width, Core.camera.height ); diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 25e68576e4..5640d67af6 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -647,7 +647,7 @@ public class NetServer implements ApplicationListener{ float xVelocity, float yVelocity, Tile mining, boolean boosting, boolean shooting, boolean chatting, boolean building, - @Nullable Queue plans, + Block selectedBlock, int selectedRotation, @Nullable Queue plans, float viewX, float viewY, float viewWidth, float viewHeight ){ NetConnection con = player.con; @@ -686,6 +686,8 @@ public class NetServer implements ApplicationListener{ player.typing = chatting; player.shooting = shooting; player.boosting = boosting; + player.selectedBlock = selectedBlock; + player.selectedRotation = selectedRotation; @Nullable var unit = player.unit(); diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index 6bf426c4e4..3b32fe410a 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -21,6 +21,7 @@ import mindustry.net.Administration.*; import mindustry.net.*; import mindustry.net.Packets.*; import mindustry.ui.*; +import mindustry.world.*; import mindustry.world.blocks.storage.*; import mindustry.world.blocks.storage.CoreBlock.*; @@ -37,6 +38,8 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra transient @Nullable NetConnection con; @ReadOnly Team team = Team.sharded; @SyncLocal boolean typing, shooting, boosting; + @SyncLocal @Nullable Block selectedBlock; + @SyncLocal int selectedRotation; @SyncLocal float mouseX, mouseY; /** command the unit had before it was controlled. */ @Nullable @NoSync UnitCommand lastCommand; diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 6b44ec2b7e..c814343a5a 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -276,6 +276,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case mining -> mining() ? 1 : 0; case mineX -> mining() ? mineTile.x : -1; case mineY -> mining() ? mineTile.y : -1; + case buildX -> isBuilding() ? buildPlan().x : -1; + case buildY -> isBuilding() ? buildPlan().y : -1; case armor -> armorOverride >= 0f ? armorOverride : armor; case flag -> flag; case speed -> type.speed * 60f / tilesize * speedMultiplier; @@ -289,6 +291,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I case payloadCapacity -> type.payloadCapacity / tilePayload; case size -> hitSize / tilesize; case color -> Color.toDoubleBits(team.color.r, team.color.g, team.color.b, 1f); + case selectedRotation -> controller instanceof Player p ? p.selectedRotation : 0; default -> Float.NaN; }; } @@ -304,6 +307,9 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I (pay.payloads().isEmpty() ? null : pay.payloads().peek() instanceof UnitPayload p1 ? p1.unit.type : pay.payloads().peek() instanceof BuildPayload p2 ? p2.block() : null) : null; + case building -> isBuilding() && !buildPlan().breaking ? buildPlan().tile().build : null; + case breaking -> isBuilding() && buildPlan().breaking ? buildPlan().tile().build : null; + case selectedBlock -> controller instanceof Player p ? p.selectedBlock : null; default -> noSensed; }; } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 3335642327..68bb108c22 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -944,6 +944,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ block = null; } + player.selectedBlock = block; + player.selectedRotation = rotation; + wasShooting = player.shooting; //only reset the controlled type and control a unit after the timer runs out diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index c0b1b753d1..18f4049b3f 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -392,11 +392,12 @@ public class TypeIO{ } public static void writeBlock(Writes write, Block block){ - write.s(block.id); + write.s(block == null ? -1 : block.id); } public static Block readBlock(Reads read){ - return content.block(read.s()); + short id = read.s(); + return id == -1 ? null : content.block(id); } /** @return the maximum acceptable amount of plans to send over the network */ diff --git a/core/src/mindustry/logic/LAccess.java b/core/src/mindustry/logic/LAccess.java index 5f3b25f890..91c4e70113 100644 --- a/core/src/mindustry/logic/LAccess.java +++ b/core/src/mindustry/logic/LAccess.java @@ -51,6 +51,10 @@ public enum LAccess{ mineX, mineY, mining, + buildX, + buildY, + building, + breaking, speed, team, type, @@ -64,6 +68,8 @@ public enum LAccess{ payloadCapacity, maxUnits, id, + selectedBlock, + selectedRotation, //values with parameters are considered controllable enabled("to"), //"to" is standard for single parameter access diff --git a/core/src/mindustry/world/blocks/ConstructBlock.java b/core/src/mindustry/world/blocks/ConstructBlock.java index 68a5475d19..f8bf94b418 100644 --- a/core/src/mindustry/world/blocks/ConstructBlock.java +++ b/core/src/mindustry/world/blocks/ConstructBlock.java @@ -212,8 +212,19 @@ public class ConstructBlock extends Block{ @Override public double sense(LAccess sensor){ - if(sensor == LAccess.progress) return Mathf.clamp(progress); - return super.sense(sensor); + return switch(sensor){ + case progress -> Mathf.clamp(progress); + case breaking -> activeDeconstruct ? 1 : 0; + default -> super.sense(sensor); + }; + } + + @Override + public Object senseObject(LAccess sensor){ + return switch(sensor){ + case building -> current; + default -> super.senseObject(sensor); + }; } @Override diff --git a/core/src/mindustry/world/blocks/defense/BuildTurret.java b/core/src/mindustry/world/blocks/defense/BuildTurret.java index 58bd7912f1..e5616694bf 100644 --- a/core/src/mindustry/world/blocks/defense/BuildTurret.java +++ b/core/src/mindustry/world/blocks/defense/BuildTurret.java @@ -13,6 +13,7 @@ import mindustry.game.Teams.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.io.*; +import mindustry.logic.*; import mindustry.type.*; import mindustry.world.*; import mindustry.world.blocks.ConstructBlock.*; @@ -264,5 +265,21 @@ public class BuildTurret extends BaseTurret{ } } } + + @Override + public double sense(LAccess sensor){ + return switch(sensor){ + case buildX, buildY -> unit.sense(sensor); + default -> super.sense(sensor); + }; + } + + @Override + public Object senseObject(LAccess sensor){ + return switch(sensor){ + case building, breaking -> unit.senseObject(sensor); + default -> super.senseObject(sensor); + }; + } } }