diff --git a/core/src/mindustry/ai/types/FlyingAI.java b/core/src/mindustry/ai/types/FlyingAI.java index 538ab2fe2b..dd9530254b 100644 --- a/core/src/mindustry/ai/types/FlyingAI.java +++ b/core/src/mindustry/ai/types/FlyingAI.java @@ -1,7 +1,98 @@ package mindustry.ai.types; +import arc.math.*; +import arc.math.geom.*; +import arc.util.*; +import mindustry.*; +import mindustry.entities.*; import mindustry.entities.units.*; +import mindustry.world.meta.*; public class FlyingAI extends AIController{ + @Override + public void update(){ + unit.rotation(unit.vel().angle()); + + if(Units.invalidateTarget(target, unit.team(), unit.x(), unit.y())){ + target = null; + } + + if(retarget()){ + targetClosest(); + + if(target == null) targetClosestEnemyFlag(BlockFlag.producer); + if(target == null) targetClosestEnemyFlag(BlockFlag.turret); + } + + boolean shoot = false; + + if(target != null){ + attack(40f); + + shoot = unit.inRange(target); + + if(shoot && unit.type().hasWeapons()){ + Vec2 to = Predict.intercept(unit, target, unit.type().weapons.first().bullet.speed); + unit.aim(to); + } + }else{ + target = unit.closestCore(); + moveTo(Vars.state.rules.dropZoneRadius + 120f); + } + + unit.controlWeapons(shoot, shoot); + } + + 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); + + float ang = unit.angleTo(target); + float diff = Angles.angleDist(ang, unit.rotation()); + + if(diff > 100f && vec.len() < circleLength){ + vec.setAngle(unit.vel().angle()); + }else{ + vec.setAngle(Mathf.slerpDelta(unit.vel().angle(), vec.angle(), 0.44f)); + } + + vec.setLength(unit.type().speed * Time.delta()); + + unit.moveAt(vec); + } } diff --git a/core/src/mindustry/ai/types/GroundAI.java b/core/src/mindustry/ai/types/GroundAI.java index a045620292..7a9e97ae12 100644 --- a/core/src/mindustry/ai/types/GroundAI.java +++ b/core/src/mindustry/ai/types/GroundAI.java @@ -13,7 +13,20 @@ import static mindustry.Vars.pathfinder; public class GroundAI extends AIController{ @Override - public void behavior(){ + public void update(){ + if(Units.invalidateTarget(target, unit.team(), unit.x(), unit.y(), Float.MAX_VALUE)){ + target = null; + + //TODO this is hacky, cleanup + if(unit instanceof Legsc){ + unit.lookAt(((Legsc)unit).baseRotation()); + } + } + + if(retarget()){ + targetClosest(); + } + //attack Tilec core = unit.closestEnemyCore(); @@ -43,23 +56,6 @@ public class GroundAI extends AIController{ unit.controlWeapons(rotate, shoot); } - @Override - public void targeting(){ - - if(Units.invalidateTarget(target, unit.team(), unit.x(), unit.y(), Float.MAX_VALUE)){ - target = null; - - //TODO this is hacky, cleanup - if(unit instanceof Legsc){ - unit.lookAt(((Legsc)unit).baseRotation()); - } - } - - if(retarget()){ - targetClosest(); - } - } - protected void moveToCore(PathTarget path){ Tile tile = unit.tileOn(); if(tile == null) return; diff --git a/core/src/mindustry/entities/def/WeaponsComp.java b/core/src/mindustry/entities/def/WeaponsComp.java index 8bf7dc6916..0dc04a3061 100644 --- a/core/src/mindustry/entities/def/WeaponsComp.java +++ b/core/src/mindustry/entities/def/WeaponsComp.java @@ -23,6 +23,10 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{ @ReadOnly WeaponMount[] mounts = {}; @ReadOnly float range; + boolean inRange(Position other){ + return within(other, range); + } + void setupWeapons(UnitType def){ mounts = new WeaponMount[def.weapons.size]; range = 0f; diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 7ef4805e4c..1b2c6b8ccb 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -4,6 +4,10 @@ import arc.math.geom.*; import arc.util.*; import mindustry.entities.*; import mindustry.gen.*; +import mindustry.world.*; +import mindustry.world.meta.*; + +import static mindustry.Vars.indexer; public class AIController implements UnitController{ protected static final Vec2 vec = new Vec2(); @@ -15,8 +19,17 @@ public class AIController implements UnitController{ @Override public void update(){ - targeting(); - behavior(); + + } + + protected void targetClosestAllyFlag(BlockFlag flag){ + Tile target = Geometry.findClosest(unit.x(), unit.y(), indexer.getAllied(unit.team(), flag)); + if(target != null) this.target = target.entity; + } + + protected void targetClosestEnemyFlag(BlockFlag flag){ + Tile target = Geometry.findClosest(unit.x(), unit.y(), indexer.getEnemy(unit.team(), flag)); + if(target != null) this.target = target.entity; } protected boolean retarget(){ @@ -30,15 +43,6 @@ public class AIController implements UnitController{ } } - - public void targeting(){ - - } - - public void behavior(){ - - } - @Override public void unit(Unitc unit){ this.unit = unit; diff --git a/gradle.properties b/gradle.properties index 1d264aa135..e4c388296b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ org.gradle.daemon=true org.gradle.jvmargs=-Xms256m -Xmx1024m -archash=f0eda1168b1230b6ce6c7ecee6b51eaf2048d856 +archash=ff7229bd2071e3fabb9bdc0b18ef6ca90e3200f7