Added basic flying AI
This commit is contained in:
@@ -1,7 +1,98 @@
|
|||||||
package mindustry.ai.types;
|
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.entities.units.*;
|
||||||
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
public class FlyingAI extends AIController{
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,20 @@ import static mindustry.Vars.pathfinder;
|
|||||||
public class GroundAI extends AIController{
|
public class GroundAI extends AIController{
|
||||||
|
|
||||||
@Override
|
@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
|
//attack
|
||||||
Tilec core = unit.closestEnemyCore();
|
Tilec core = unit.closestEnemyCore();
|
||||||
|
|
||||||
@@ -43,23 +56,6 @@ public class GroundAI extends AIController{
|
|||||||
unit.controlWeapons(rotate, shoot);
|
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){
|
protected void moveToCore(PathTarget path){
|
||||||
Tile tile = unit.tileOn();
|
Tile tile = unit.tileOn();
|
||||||
if(tile == null) return;
|
if(tile == null) return;
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ abstract class WeaponsComp implements Teamc, Posc, Rotc{
|
|||||||
@ReadOnly WeaponMount[] mounts = {};
|
@ReadOnly WeaponMount[] mounts = {};
|
||||||
@ReadOnly float range;
|
@ReadOnly float range;
|
||||||
|
|
||||||
|
boolean inRange(Position other){
|
||||||
|
return within(other, range);
|
||||||
|
}
|
||||||
|
|
||||||
void setupWeapons(UnitType def){
|
void setupWeapons(UnitType def){
|
||||||
mounts = new WeaponMount[def.weapons.size];
|
mounts = new WeaponMount[def.weapons.size];
|
||||||
range = 0f;
|
range = 0f;
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ import arc.math.geom.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.indexer;
|
||||||
|
|
||||||
public class AIController implements UnitController{
|
public class AIController implements UnitController{
|
||||||
protected static final Vec2 vec = new Vec2();
|
protected static final Vec2 vec = new Vec2();
|
||||||
@@ -15,8 +19,17 @@ public class AIController implements UnitController{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
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(){
|
protected boolean retarget(){
|
||||||
@@ -30,15 +43,6 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void targeting(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void behavior(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unit(Unitc unit){
|
public void unit(Unitc unit){
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=f0eda1168b1230b6ce6c7ecee6b51eaf2048d856
|
archash=ff7229bd2071e3fabb9bdc0b18ef6ca90e3200f7
|
||||||
|
|||||||
Reference in New Issue
Block a user