Better builder AI / Various tweaks
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package mindustry.ai.types;
|
package mindustry.ai.types;
|
||||||
|
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -10,6 +12,9 @@ import mindustry.world.blocks.ConstructBlock.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class BuilderAI extends AIController{
|
public class BuilderAI extends AIController{
|
||||||
|
float buildRadius = 700;
|
||||||
|
boolean found = false;
|
||||||
|
@Nullable Builderc following;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUnit(){
|
public void updateUnit(){
|
||||||
@@ -21,8 +26,23 @@ public class BuilderAI extends AIController{
|
|||||||
|
|
||||||
builder.updateBuilding(true);
|
builder.updateBuilding(true);
|
||||||
|
|
||||||
//approach request if building
|
if(following != null){
|
||||||
|
//try to follow and mimic someone
|
||||||
|
|
||||||
|
//validate follower
|
||||||
|
if(!following.isValid() || !following.activelyBuilding()){
|
||||||
|
following = null;
|
||||||
|
builder.plans().clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set to follower's first build plan, whatever that is
|
||||||
|
builder.plans().clear();
|
||||||
|
builder.plans().addFirst(following.buildPlan());
|
||||||
|
}
|
||||||
|
|
||||||
if(builder.buildPlan() != null){
|
if(builder.buildPlan() != null){
|
||||||
|
//approach request if building
|
||||||
BuildPlan req = builder.buildPlan();
|
BuildPlan req = builder.buildPlan();
|
||||||
|
|
||||||
boolean valid =
|
boolean valid =
|
||||||
@@ -39,8 +59,35 @@ public class BuilderAI extends AIController{
|
|||||||
builder.plans().removeFirst();
|
builder.plans().removeFirst();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
|
//follow someone and help them build
|
||||||
|
if(timer.get(timerTarget2, 60f)){
|
||||||
|
found = false;
|
||||||
|
|
||||||
|
Units.nearby(unit.team, unit.x, unit.y, buildRadius, u -> {
|
||||||
|
if(found) return;
|
||||||
|
|
||||||
|
if(u instanceof Builderc && u != unit && ((Builderc)u).activelyBuilding()){
|
||||||
|
Builderc b = (Builderc)u;
|
||||||
|
BuildPlan plan = b.buildPlan();
|
||||||
|
|
||||||
|
Building build = world.build(plan.x, plan.y);
|
||||||
|
if(build instanceof ConstructBuild){
|
||||||
|
ConstructBuild cons = (ConstructBuild)build;
|
||||||
|
float dist = Math.min(cons.dst(unit) - buildingRange, 0);
|
||||||
|
|
||||||
|
//make sure you can reach the request in time
|
||||||
|
if(dist / unit.type().speed < cons.buildCost * 0.9f){
|
||||||
|
following = b;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//find new request
|
//find new request
|
||||||
if(!unit.team().data().blocks.isEmpty()){
|
if(!unit.team().data().blocks.isEmpty() && following == null){
|
||||||
Queue<BlockPlan> blocks = unit.team().data().blocks;
|
Queue<BlockPlan> blocks = unit.team().data().blocks;
|
||||||
BlockPlan block = blocks.first();
|
BlockPlan block = blocks.first();
|
||||||
|
|
||||||
@@ -56,6 +103,7 @@ public class BuilderAI extends AIController{
|
|||||||
blocks.addLast(block);
|
blocks.addLast(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,8 @@ public class UnitTypes implements ContentList{
|
|||||||
//ground
|
//ground
|
||||||
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
public static @EntityDef({Unitc.class, Mechc.class}) UnitType mace, dagger, crawler, fortress, scepter, reign;
|
||||||
|
|
||||||
//ground + builder
|
|
||||||
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class}) UnitType nova;
|
|
||||||
|
|
||||||
//ground + builder + miner + commander
|
//ground + builder + miner + commander
|
||||||
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class, Minerc.class, Commanderc.class}) UnitType pulsar, quasar;
|
public static @EntityDef({Unitc.class, Mechc.class, Builderc.class, Minerc.class, Commanderc.class}) UnitType nova, pulsar, quasar;
|
||||||
|
|
||||||
//legs
|
//legs
|
||||||
public static @EntityDef({Unitc.class, Legsc.class}) UnitType atrax;
|
public static @EntityDef({Unitc.class, Legsc.class}) UnitType atrax;
|
||||||
@@ -252,6 +249,7 @@ public class UnitTypes implements ContentList{
|
|||||||
health = 110f;
|
health = 110f;
|
||||||
buildSpeed = 0.8f;
|
buildSpeed = 0.8f;
|
||||||
armor = 1f;
|
armor = 1f;
|
||||||
|
commandLimit = 8;
|
||||||
|
|
||||||
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
|
abilities.add(new HealFieldAbility(10f, 60f * 4, 60f));
|
||||||
|
|
||||||
@@ -279,7 +277,7 @@ public class UnitTypes implements ContentList{
|
|||||||
|
|
||||||
mineTier = 2;
|
mineTier = 2;
|
||||||
mineSpeed = 5f;
|
mineSpeed = 5f;
|
||||||
commandLimit = 8;
|
commandLimit = 15;
|
||||||
|
|
||||||
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
|
abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f));
|
||||||
|
|
||||||
@@ -320,6 +318,8 @@ public class UnitTypes implements ContentList{
|
|||||||
armor = 9f;
|
armor = 9f;
|
||||||
landShake = 2f;
|
landShake = 2f;
|
||||||
|
|
||||||
|
commandLimit = 24;
|
||||||
|
|
||||||
speed = 0.4f;
|
speed = 0.4f;
|
||||||
hitsize = 10f;
|
hitsize = 10f;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class LiquidBulletType extends BulletType{
|
|||||||
this.status = liquid.effect;
|
this.status = liquid.effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ammoMultiplier = 1f;
|
||||||
lifetime = 74f;
|
lifetime = 74f;
|
||||||
statusDuration = 60f * 2f;
|
statusDuration = 60f * 2f;
|
||||||
despawnEffect = Fx.none;
|
despawnEffect = Fx.none;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import static mindustry.Vars.*;
|
|||||||
public class AIController implements UnitController{
|
public class AIController implements UnitController{
|
||||||
protected static final Vec2 vec = new Vec2();
|
protected static final Vec2 vec = new Vec2();
|
||||||
protected static final int timerTarget = 0;
|
protected static final int timerTarget = 0;
|
||||||
|
protected static final int timerTarget2 = 1;
|
||||||
|
|
||||||
protected Unit unit;
|
protected Unit unit;
|
||||||
protected Interval timer = new Interval(4);
|
protected Interval timer = new Interval(4);
|
||||||
@@ -27,6 +28,7 @@ public class AIController implements UnitController{
|
|||||||
|
|
||||||
{
|
{
|
||||||
timer.reset(0, Mathf.random(40f));
|
timer.reset(0, Mathf.random(40f));
|
||||||
|
timer.reset(1, Mathf.random(60f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public class LiquidTurret extends Turret{
|
|||||||
public BulletType useAmmo(){
|
public BulletType useAmmo(){
|
||||||
if(cheating()) return ammoTypes.get(liquids.current());
|
if(cheating()) return ammoTypes.get(liquids.current());
|
||||||
BulletType type = ammoTypes.get(liquids.current());
|
BulletType type = ammoTypes.get(liquids.current());
|
||||||
liquids.remove(liquids.current(), type.ammoMultiplier);
|
liquids.remove(liquids.current(), 1f / type.ammoMultiplier);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ public class LiquidTurret extends Turret{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasAmmo(){
|
public boolean hasAmmo(){
|
||||||
return ammoTypes.get(liquids.current()) != null && liquids.total() >= ammoTypes.get(liquids.current()).ammoMultiplier;
|
return ammoTypes.get(liquids.current()) != null && liquids.total() >= 1f / ammoTypes.get(liquids.current()).ammoMultiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,7 +131,7 @@ public class LiquidTurret extends Turret{
|
|||||||
public boolean acceptLiquid(Building source, Liquid liquid, float amount){
|
public boolean acceptLiquid(Building source, Liquid liquid, float amount){
|
||||||
return ammoTypes.get(liquid) != null
|
return ammoTypes.get(liquid) != null
|
||||||
&& (liquids.current() == liquid || (ammoTypes.containsKey(liquids.current())
|
&& (liquids.current() == liquid || (ammoTypes.containsKey(liquids.current())
|
||||||
&& liquids.get(liquids.current()) <= ammoTypes.get(liquids.current()).ammoMultiplier + 0.001f));
|
&& liquids.get(liquids.current()) <= 1f / ammoTypes.get(liquids.current()).ammoMultiplier + 0.001f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user