Simple mining AI

This commit is contained in:
Anuken
2020-08-12 00:08:23 -04:00
parent 8810cf037e
commit 925b1e3057
11 changed files with 150 additions and 68 deletions

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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<Item> 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(){
}
}