diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index a0d3fd7682..2727246299 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1537,6 +1537,8 @@ lst.unitcontrol = Control the currently bound unit. lst.unitradar = Locate units around the currently bound unit. lst.unitlocate = Locate a specific type of position/building anywhere on the map.\nRequires a bound unit. +logic.nounitbuild = [red]Unit building logic is not allowed here. + lenum.type = Type of building/unit.\ne.g. for any router, this will return [accent]@router[].\nNot a string. lenum.shoot = Shoot at a position. lenum.shootp = Shoot at a unit/building with velocity prediction. @@ -1639,6 +1641,7 @@ unitlocate.outx = Output X coordinate. unitlocate.outy = Output Y coordinate. unitlocate.group = Building group to look for. +lenum.idle = Don't move, but keep building/mining.\nThe default state. lenum.stop = Stop moving/mining/building. lenum.move = Move to exact position. lenum.approach = Approach a position with a radius. diff --git a/core/src/mindustry/ai/types/LogicAI.java b/core/src/mindustry/ai/types/LogicAI.java index 5f72520729..abd76201e6 100644 --- a/core/src/mindustry/ai/types/LogicAI.java +++ b/core/src/mindustry/ai/types/LogicAI.java @@ -19,7 +19,7 @@ public class LogicAI extends AIController{ /** Time after which the unit resets its controlled and reverts to a normal unit. */ public static final float logicControlTimeout = 10f * 60f; - public LUnitControl control = LUnitControl.stop; + public LUnitControl control = LUnitControl.idle; public float moveX, moveY, moveRad; public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer; @Nullable diff --git a/core/src/mindustry/entities/comp/BuildingComp.java b/core/src/mindustry/entities/comp/BuildingComp.java index 407fe6a9d1..4a6ba5b1d4 100644 --- a/core/src/mindustry/entities/comp/BuildingComp.java +++ b/core/src/mindustry/entities/comp/BuildingComp.java @@ -962,8 +962,19 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc, lastAccessed = builder.getPlayer().name; } + Log.info("@ configured @ with @", builder, this, value); + if(block.configurations.containsKey(type)){ block.configurations.get(type).get(this, value); + }else if(value instanceof Building build){ + Log.info("conf w build"); + //copy config of another building + var conf = build.config(); + if(conf != null && !(conf instanceof Building)){ + configured(builder, conf); + }else{ + Log.info("no build"); + } } } diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index 538422fef0..9b95bbf7d3 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -50,6 +50,8 @@ public class Rules{ public float unitBuildSpeedMultiplier = 1f; /** How much damage any other units deal. */ public float unitDamageMultiplier = 1f; + /** Whether to allow units to build with logic. */ + public boolean logicUnitBuild = true; /** How much health blocks start with. */ public float blockHealthMultiplier = 1f; /** How much damage blocks (turrets) deal. */ diff --git a/core/src/mindustry/game/Schematics.java b/core/src/mindustry/game/Schematics.java index 92179b7c9c..e0e067a029 100644 --- a/core/src/mindustry/game/Schematics.java +++ b/core/src/mindustry/game/Schematics.java @@ -27,6 +27,7 @@ import mindustry.input.Placement.*; import mindustry.io.*; import mindustry.world.*; import mindustry.world.blocks.*; +import mindustry.world.blocks.ConstructBlock.*; import mindustry.world.blocks.distribution.*; import mindustry.world.blocks.legacy.*; import mindustry.world.blocks.power.*; @@ -357,10 +358,11 @@ public class Schematics implements Loadable{ for(int cx = x; cx <= x2; cx++){ for(int cy = y; cy <= y2; cy++){ Building linked = world.build(cx, cy); + Block realBlock = linked == null ? null : linked instanceof ConstructBuild cons ? cons.cblock : linked.block; - if(linked != null && (linked.block.isVisible() || linked.block() instanceof CoreBlock) && !(linked.block instanceof ConstructBlock)){ - int top = linked.block.size/2; - int bot = linked.block.size % 2 == 1 ? -linked.block.size/2 : -(linked.block.size - 1)/2; + if(linked != null && (realBlock.isVisible() || realBlock instanceof CoreBlock)){ + int top = realBlock.size/2; + int bot = realBlock.size % 2 == 1 ? -realBlock.size/2 : -(realBlock.size - 1)/2; minx = Math.min(linked.tileX() + bot, minx); miny = Math.min(linked.tileY() + bot, miny); maxx = Math.max(linked.tileX() + top, maxx); @@ -385,12 +387,13 @@ public class Schematics implements Loadable{ for(int cx = ox; cx <= ox2; cx++){ for(int cy = oy; cy <= oy2; cy++){ Building tile = world.build(cx, cy); + Block realBlock = tile == null ? null : tile instanceof ConstructBuild cons ? cons.cblock : tile.block; - if(tile != null && !counted.contains(tile.pos()) && !(tile.block instanceof ConstructBlock) - && (tile.block.isVisible() || tile.block instanceof CoreBlock)){ + if(tile != null && !counted.contains(tile.pos()) + && (realBlock.isVisible() || realBlock instanceof CoreBlock)){ Object config = tile.config(); - tiles.add(new Stile(tile.block, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation)); + tiles.add(new Stile(realBlock, tile.tileX() + offsetX, tile.tileY() + offsetY, config, (byte)tile.rotation)); counted.add(tile.pos()); } } diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 6c4ec55281..c7082e4cb1 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -447,7 +447,7 @@ public class LExecutor{ } } case build -> { - if(unit.canBuild() && exec.obj(p3) instanceof Block block){ + if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block){ int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize); int rot = exec.numi(p4); @@ -458,12 +458,14 @@ public class LExecutor{ ai.plan.stuck = false; } + var conf = exec.obj(p5); ai.plan.set(x, y, rot, block); - ai.plan.config = exec.obj(p5) instanceof Content c ? c : null; + ai.plan.config = conf instanceof Content c ? c : conf instanceof Building b ? b : null; unit.clearBuilding(); + Tile tile = ai.plan.tile(); - if(ai.plan.tile() != null){ + if(tile != null && !(tile.block() == block && tile.build != null && tile.build.rotation == rot)){ unit.updateBuilding = true; unit.addBuild(ai.plan); } diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 15735359a7..21fddc023f 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -829,7 +829,11 @@ public class LStatements{ table.button(b -> { b.label(() -> type.name()); b.clicked(() -> showSelect(b, LUnitControl.all, type, t -> { - type = t; + if(t == LUnitControl.build && !Vars.state.rules.logicUnitBuild){ + Vars.ui.showInfo("@logic.nounitbuild"); + }else{ + type = t; + } rebuild(table); }, 2, cell -> cell.size(120, 50))); }, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2); diff --git a/core/src/mindustry/logic/LUnitControl.java b/core/src/mindustry/logic/LUnitControl.java index 41f00da025..f5bc4dbd52 100644 --- a/core/src/mindustry/logic/LUnitControl.java +++ b/core/src/mindustry/logic/LUnitControl.java @@ -1,6 +1,7 @@ package mindustry.logic; public enum LUnitControl{ + idle, stop, move("x", "y"), approach("x", "y", "radius"),