diff --git a/core/src/mindustry/ai/WaveSpawner.java b/core/src/mindustry/ai/WaveSpawner.java index c1947f4da4..a5d35446a4 100644 --- a/core/src/mindustry/ai/WaveSpawner.java +++ b/core/src/mindustry/ai/WaveSpawner.java @@ -198,7 +198,8 @@ public class WaveSpawner{ } } - private void spawnEffect(Unit unit){ + /** Applies the standard wave spawn effects to a unit - invincibility, unmoving. */ + public void spawnEffect(Unit unit){ unit.rotation = unit.angleTo(world.width()/2f * tilesize, world.height()/2f * tilesize); unit.apply(StatusEffects.unmoving, 30f); unit.apply(StatusEffects.invincible, 60f); diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index f52a2b4503..27a963dae3 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -3744,9 +3744,7 @@ public class Blocks{ hasLiquids = true; instructionsPerTick = 25; - range = 8 * 42; - size = 3; }}; @@ -3783,7 +3781,8 @@ public class Blocks{ //currently incomplete, debugOnly for now requirements(Category.logic, BuildVisibility.debugOnly, with()); - instructionsPerTick = 2; + //TODO customizable IPT + instructionsPerTick = 8; forceDark = true; privileged = true; size = 1; diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 5d85325d1d..0222f9d08e 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -118,6 +118,9 @@ public class TypeIO{ write.b((byte)19); write.f(v.x); write.f(v.y); + }else if(object instanceof Team t){ + write.b((byte)20); + write.b(t.id); }else{ throw new IllegalArgumentException("Unknown object type: " + object.getClass()); } @@ -177,6 +180,7 @@ public class TypeIO{ yield out; } case 19 -> new Vec2(read.f(), read.f()); + case 20 -> Team.all[read.ub()]; default -> throw new IllegalArgumentException("Unknown object type: " + type); }; } diff --git a/core/src/mindustry/logic/GlobalConstants.java b/core/src/mindustry/logic/GlobalConstants.java index 0bd4d85dc5..bb00e579d3 100644 --- a/core/src/mindustry/logic/GlobalConstants.java +++ b/core/src/mindustry/logic/GlobalConstants.java @@ -9,6 +9,7 @@ import mindustry.*; import mindustry.content.*; import mindustry.ctype.*; import mindustry.entities.units.*; +import mindustry.game.*; import mindustry.logic.LExecutor.*; import mindustry.type.*; import mindustry.world.*; @@ -53,6 +54,10 @@ public class GlobalConstants{ //store base content + for(Team team : Team.baseTeams){ + put("@" + team.name, team); + } + for(Item item : Vars.content.items()){ put("@" + item.name, item); } diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index d069c1d444..6173ab0aa8 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -216,7 +216,7 @@ public class LExecutor{ //no units of this type found exec.setconst(varUnit, null); } - }else if(exec.obj(type) instanceof Unit u && u.team == exec.team && u.type.logicControllable){ + }else if(exec.obj(type) instanceof Unit u && (u.team == exec.team || exec.privileged) && u.type.logicControllable){ //bind to specific unit object exec.setconst(varUnit, u); }else{ @@ -966,6 +966,7 @@ public class LExecutor{ obj instanceof Building build ? build.block.name : obj instanceof Unit unit ? unit.type.name : obj instanceof Enum e ? e.name() : + obj instanceof Team team ? team.name : "[object]"; } } @@ -1156,5 +1157,36 @@ public class LExecutor{ } } + public static class SpawnUniI implements LInstruction{ + public int type, x, y, rotation, team, result; + public boolean effect; + + public SpawnUniI(int type, int x, int y, int rotation, int team, boolean effect, int result){ + this.type = type; + this.x = x; + this.y = y; + this.rotation = rotation; + this.team = team; + this.effect = effect; + this.result = result; + } + + public SpawnUniI(){ + } + + @Override + public void run(LExecutor exec){ + if(exec.obj(type) instanceof UnitType type && !type.hidden && exec.obj(team) instanceof Team team && Units.canCreate(team, type)){ + //random offset to prevent stacking + var unit = type.spawn(team, World.unconv(exec.numf(x)) + Mathf.range(0.01f), World.unconv(exec.numf(y)) + Mathf.range(0.01f)); + unit.rotation = exec.numf(rotation); + if(effect){ + spawner.spawnEffect(unit); + } + exec.setobj(result, unit); + } + } + } + //endregion } diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index df3f95f76e..bfb74be403 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -105,8 +105,8 @@ public abstract class LStatement{ return field(table, value, setter).width(85f).padRight(10).left(); } - protected void fields(Table table, String value, Cons setter){ - field(table, value, setter).width(85f); + protected Cell fields(Table table, String value, Cons setter){ + return field(table, value, setter).width(85f); } protected void row(Table table){ diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index af5fc44bfb..55f496d9a0 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -1154,4 +1154,55 @@ public class LStatements{ return new SetBlockI(builder.var(x), builder.var(y), builder.var(block), builder.var(team), builder.var(rotation), layer); } } + + @RegisterStatement("spawn") + public static class SpawnUnitStatement extends LStatement{ + public String type = "@dagger", x = "10", y = "10", rotation = "90", team = "@sharded", result = "result"; + public boolean effect = true; + + @Override + public void build(Table table){ + fields(table, result, str -> result = str); + + table.add(" = spawn "); + field(table, type, str -> type = str); + + row(table); + + table.add(" at "); + fields(table, x, str -> x = str); + + table.add(", "); + fields(table, y, str -> y = str); + + table.row(); + + table.add(); + + table.add("team "); + field(table, team, str -> team = str); + + table.add(" rot "); + fields(table, rotation, str -> rotation = str).left(); + + //effect mostly unnecessary and looks bad + //row(table); + //table.check("effect", effect, val -> effect = val); + } + + @Override + public boolean privileged(){ + return true; + } + + @Override + public Color color(){ + return Pal.logicWorld; + } + + @Override + public LInstruction build(LAssembler builder){ + return new SpawnUniI(builder.var(type), builder.var(x), builder.var(y), builder.var(rotation), builder.var(team), effect, builder.var(result)); + } + } } diff --git a/core/src/mindustry/world/blocks/units/UnitAssembler.java b/core/src/mindustry/world/blocks/units/UnitAssembler.java index f22cd0de96..cf4554c6b7 100644 --- a/core/src/mindustry/world/blocks/units/UnitAssembler.java +++ b/core/src/mindustry/world/blocks/units/UnitAssembler.java @@ -384,6 +384,7 @@ public class UnitAssembler extends PayloadBlock{ var plan = plan(); //draw the unit construction as outline + //TODO flashes when no gallium Draw.draw(Layer.blockBuilding, () -> { Draw.color(Pal.accent, warmup); @@ -420,6 +421,9 @@ public class UnitAssembler extends PayloadBlock{ Drawf.buildBeam(px, py, spawn.x, spawn.y, plan.unit.hitSize/2f); } + //fill square in middle + Fill.square(spawn.x, spawn.y, plan.unit.hitSize/2f); + Draw.reset(); Draw.z(Layer.buildBeam);