diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index a606592b26..6db5e3e4c3 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -1,9 +1,6 @@ package mindustry.ai.types; -import arc.math.*; -import arc.math.geom.*; import arc.struct.*; -import arc.util.*; import mindustry.entities.units.*; import mindustry.game.Teams.*; import mindustry.gen.*; @@ -63,19 +60,4 @@ public class BuilderAI extends AIController{ } } } - - protected void moveTo(Position target, float circleLength){ - vec.set(target).sub(unit); - - float length = circleLength <= 0.001f ? 1f : Mathf.clamp((unit.dst(target) - circleLength) / 100f, -1f, 1f); - - vec.setLength(unit.type().speed * Time.delta * length); - if(length < -0.5f){ - vec.rotate(180f); - }else if(length < 0){ - vec.setZero(); - } - - unit.moveAt(vec); - } } diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java index 2a09c1403c..479e2ce817 100644 --- a/core/src/mindustry/ai/types/FlyingAI.java +++ b/core/src/mindustry/ai/types/FlyingAI.java @@ -20,7 +20,7 @@ public class FlyingAI extends AIController{ if(target != null && unit.hasWeapons()){ if(unit.type().weapons.first().rotate){ - moveTo(unit.range() * 0.8f); + moveTo(target, unit.range() * 0.8f); unit.lookAt(target); }else{ attack(80f); @@ -44,41 +44,6 @@ public class FlyingAI extends AIController{ //TODO clean up - protected void circle(float circleLength){ - circle(circleLength, unit.type().speed); - } - - protected void circle(float circleLength, float speed){ - if(target == null) return; - - vec.set(target).sub(unit); - - if(vec.len() < circleLength){ - vec.rotate((circleLength - vec.len()) / circleLength * 180f); - } - - vec.setLength(speed * Time.delta); - - unit.moveAt(vec); - } - - protected void moveTo(float circleLength){ - if(target == null) return; - - vec.set(target).sub(unit); - - float length = circleLength <= 0.001f ? 1f : Mathf.clamp((unit.dst(target) - circleLength) / 100f, -1f, 1f); - - vec.setLength(unit.type().speed * Time.delta * length); - if(length < -0.5f){ - vec.rotate(180f); - }else if(length < 0){ - vec.setZero(); - } - - unit.moveAt(vec); - } - protected void attack(float circleLength){ vec.set(target).sub(unit); diff --git a/core/src/mindustry/ai/types/MinerAI.java b/core/src/mindustry/ai/types/MinerAI.java new file mode 100644 index 0000000000..9cedefdc76 --- /dev/null +++ b/core/src/mindustry/ai/types/MinerAI.java @@ -0,0 +1,93 @@ +package mindustry.ai.types; + +import arc.struct.*; +import arc.util.*; +import mindustry.content.*; +import mindustry.entities.units.*; +import mindustry.gen.*; +import mindustry.type.*; +import mindustry.world.*; + +import static mindustry.Vars.*; + +public class MinerAI extends AIController{ + //miners are limited to copper and lead until further notice + Seq targets = Seq.with(Items.copper, Items.lead); + + boolean mining = true; + Item targetItem; + Tile ore; + + @Override + protected void updateMovement(){ + if(unit.moving()){ + unit.lookAt(unit.vel.angle()); + } + + if(unit.isFlying()){ + unit.wobble(); + } + + Building core = unit.closestCore(); + + if(!(unit instanceof Minerc) || core == null) return; + + Minerc miner = (Minerc)unit; + + if(miner.mineTile() != null && !miner.mineTile().within(unit, unit.type().range)){ + miner.mineTile(null); + } + + if(mining){ + targetItem = Structs.findMin(targets, indexer::hasOre, Structs.comparingInt(i -> -core.items.get(i))); + + //core full of the target item, do nothing + if(targetItem != null && core.acceptStack(targetItem, 1, unit) == 0){ + unit.clearItem(); + return; + } + + //if inventory is full, drop it off. + if(unit.stack.amount >= unit.type().itemCapacity || (targetItem != null && !unit.acceptsItem(targetItem))){ + mining = false; + }else{ + if(retarget() && targetItem != null){ + ore = indexer.findClosestOre(unit.x, unit.y, targetItem); + } + + if(ore != null){ + moveTo(ore, unit.type().range / 1.5f); + + if(unit.within(ore, unit.type().range)){ + miner.mineTile(ore); + } + + if(ore.block() != Blocks.air){ + mining = false; + } + } + } + }else{ + if(unit.stack.amount == 0){ + mining = true; + return; + } + + if(unit.within(core, unit.type().range)){ + if(core.acceptStack(unit.stack.item, unit.stack.amount, unit) > 0){ + Call.transferItemTo(unit.stack.item, unit.stack.amount, unit.x, unit.y, core); + } + + unit.clearItem(); + mining = true; + } + + circle(core, unit.type().range / 1.8f); + } + } + + @Override + protected void updateTargeting(){ + } + +} diff --git a/core/src/mindustry/content/Fx.java b/core/src/mindustry/content/Fx.java index b1d620141d..38d82fcd7b 100644 --- a/core/src/mindustry/content/Fx.java +++ b/core/src/mindustry/content/Fx.java @@ -102,7 +102,7 @@ public class Fx{ Tmp.v1.set(e.x, e.y).interpolate(Tmp.v2.set(to), e.fin(), Interp.pow3) .add(Tmp.v2.sub(e.x, e.y).nor().rotate90(1).scl(Mathf.randomSeedRange(e.id, 1f) * e.fslope() * 10f)); float x = Tmp.v1.x, y = Tmp.v1.y; - float size = Math.min(0.8f + e.rotation / 5f, 2); + float size = 1f; stroke(e.fslope() * 2f * size, Pal.accent); Lines.circle(x, y, e.fslope() * 2f * size); diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 697dde82b3..ca2cff1ca8 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -687,13 +687,17 @@ public class UnitTypes implements ContentList{ //region air support mono = new UnitType("mono"){{ + defaultController = MinerAI::new; + flying = true; - drag = 0.05f; - accel = 0.15f; - speed = 2f; + drag = 0.06f; + accel = 0.12f; + speed = 1.1f; health = 100; engineSize = 1.8f; engineOffset = 5.7f; + itemCapacity = 30; + range = 50f; mineTier = 1; mineSpeed = 2.5f; @@ -704,7 +708,7 @@ public class UnitTypes implements ContentList{ flying = true; drag = 0.05f; - speed = 2f; + speed = 1.9f; rotateSpeed = 15f; accel = 0.1f; range = 70f; diff --git a/core/src/mindustry/entities/comp/MinerComp.java b/core/src/mindustry/entities/comp/MinerComp.java index 12711abe2e..92937f2125 100644 --- a/core/src/mindustry/entities/comp/MinerComp.java +++ b/core/src/mindustry/entities/comp/MinerComp.java @@ -45,7 +45,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{ if(accepted > 0){ Call.transferItemTo(item(), accepted, mineTile.worldx() + Mathf.range(tilesize / 2f), - mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile()); + mineTile.worldy() + Mathf.range(tilesize / 2f), core); clearItem(); } } @@ -66,7 +66,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc, Unitc{ if(within(core, mineTransferRange) && core.acceptStack(item, 1, this) == 1 && offloadImmediately()){ Call.transferItemTo(item, 1, mineTile.worldx() + Mathf.range(tilesize / 2f), - mineTile.worldy() + Mathf.range(tilesize / 2f), core.tile()); + mineTile.worldy() + Mathf.range(tilesize / 2f), core); }else if(acceptsItem(item)){ //this is clientside, since items are synced anyway InputHandler.transferItemToUnit(item, diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 5bbd462d42..f2ed8f4476 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -115,6 +115,41 @@ public class AIController implements UnitController{ } + protected void circle(Position target, float circleLength){ + circle(target, circleLength, unit.type().speed); + } + + protected void circle(Position target, float circleLength, float speed){ + if(target == null) return; + + vec.set(target).sub(unit); + + if(vec.len() < circleLength){ + vec.rotate((circleLength - vec.len()) / circleLength * 180f); + } + + vec.setLength(speed * Time.delta); + + unit.moveAt(vec); + } + + protected void moveTo(Position target, float circleLength){ + if(target == null) return; + + vec.set(target).sub(unit); + + float length = circleLength <= 0.001f ? 1f : Mathf.clamp((unit.dst(target) - circleLength) / 100f, -1f, 1f); + + vec.setLength(unit.type().speed * Time.delta * length); + if(length < -0.5f){ + vec.rotate(180f); + }else if(length < 0){ + vec.setZero(); + } + + unit.moveAt(vec); + } + @Override public void unit(Unit unit){ if(this.unit == unit) return; diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index 629c2c4153..65db381c54 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -86,12 +86,12 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ } @Remote(called = Loc.server, unreliable = true) - public static void transferItemTo(Item item, int amount, float x, float y, Tile tile){ - if(tile == null || tile.build == null || tile.build.items == null) return; + public static void transferItemTo(Item item, int amount, float x, float y, Building build){ + if(build == null || build.items == null) return; for(int i = 0; i < Mathf.clamp(amount / 3, 1, 8); i++){ - Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, tile, () -> {})); + Time.run(i * 3, () -> createItemTransfer(item, amount, x, y, build, () -> {})); } - tile.build.items.add(item, amount); + build.items.add(item, amount); } public static void createItemTransfer(Item item, int amount, float x, float y, Position to, Runnable done){ diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 839c82955f..2a17acb865 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -99,6 +99,7 @@ public class LCanvas extends Table{ void load(String asm){ Seq statements = LAssembler.read(asm); + statements.truncate(LogicBlock.maxInstructions); this.statements.clearChildren(); for(LStatement st : statements){ add(st); @@ -119,8 +120,8 @@ public class LCanvas extends Table{ } public class DragLayout extends WidgetGroup{ - float margin = 4f; - float space = 10f, prefWidth, prefHeight; + float margin = Scl.scl(4f); + float space = Scl.scl(10f), prefWidth, prefHeight; Seq seq = new Seq<>(); int insertPosition = 0; @@ -136,7 +137,7 @@ public class LCanvas extends Table{ float totalHeight = getChildren().sumf(e -> e.getHeight() + space) + margin*2f; height = prefHeight = totalHeight; - width = prefWidth = 400f; + width = prefWidth = Scl.scl(400f); //layout everything normally for(int i = 0; i < getChildren().size; i++){ diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 35598f39b9..6a2b5c9729 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -175,6 +175,7 @@ public abstract class Turret extends Block{ @Override public double sense(LAccess sensor){ + if(sensor == LAccess.rotation) return rotation; if(sensor == LAccess.shootX) return targetPos.x; if(sensor == LAccess.shootY) return targetPos.y; if(sensor == LAccess.shooting) return (isControlled() ? unit.isShooting() : logicControlled() ? logicShooting : validateTarget()) ? 1 : 0; diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index 03ee25279a..2f644a131a 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -76,6 +76,7 @@ public class LogicBlock extends Block{ public void updateCodeVars(String str, Cons assemble){ if(str != null){ + if(str.length() >= Short.MAX_VALUE) str = str.substring(0, Short.MAX_VALUE - 1); code = str; try{