diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index bd4fca20ed..d5953dfedc 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -1,6 +1,8 @@ package mindustry.ai.types; import arc.struct.*; +import arc.util.ArcAnnotate.*; +import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.game.Teams.*; import mindustry.gen.*; @@ -10,6 +12,9 @@ import mindustry.world.blocks.ConstructBlock.*; import static mindustry.Vars.*; public class BuilderAI extends AIController{ + float buildRadius = 700; + boolean found = false; + @Nullable Builderc following; @Override public void updateUnit(){ @@ -21,8 +26,23 @@ public class BuilderAI extends AIController{ 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){ + //approach request if building BuildPlan req = builder.buildPlan(); boolean valid = @@ -39,8 +59,35 @@ public class BuilderAI extends AIController{ builder.plans().removeFirst(); } }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 - if(!unit.team().data().blocks.isEmpty()){ + if(!unit.team().data().blocks.isEmpty() && following == null){ Queue blocks = unit.team().data().blocks; BlockPlan block = blocks.first(); @@ -56,6 +103,7 @@ public class BuilderAI extends AIController{ blocks.addLast(block); } } + } } } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 0666abfe9e..94d2fa1b03 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -17,11 +17,8 @@ public class UnitTypes implements ContentList{ //ground 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 - 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 public static @EntityDef({Unitc.class, Legsc.class}) UnitType atrax; @@ -252,6 +249,7 @@ public class UnitTypes implements ContentList{ health = 110f; buildSpeed = 0.8f; armor = 1f; + commandLimit = 8; abilities.add(new HealFieldAbility(10f, 60f * 4, 60f)); @@ -279,7 +277,7 @@ public class UnitTypes implements ContentList{ mineTier = 2; mineSpeed = 5f; - commandLimit = 8; + commandLimit = 15; abilities.add(new ShieldFieldAbility(20f, 40f, 60f * 5, 60f)); @@ -320,6 +318,8 @@ public class UnitTypes implements ContentList{ armor = 9f; landShake = 2f; + commandLimit = 24; + speed = 0.4f; hitsize = 10f; diff --git a/core/src/mindustry/entities/bullet/LiquidBulletType.java b/core/src/mindustry/entities/bullet/LiquidBulletType.java index 45ae536668..22d5c22d42 100644 --- a/core/src/mindustry/entities/bullet/LiquidBulletType.java +++ b/core/src/mindustry/entities/bullet/LiquidBulletType.java @@ -24,6 +24,7 @@ public class LiquidBulletType extends BulletType{ this.status = liquid.effect; } + ammoMultiplier = 1f; lifetime = 74f; statusDuration = 60f * 2f; despawnEffect = Fx.none; diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index aa95959e60..98f20b45f7 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -16,6 +16,7 @@ import static mindustry.Vars.*; public class AIController implements UnitController{ protected static final Vec2 vec = new Vec2(); protected static final int timerTarget = 0; + protected static final int timerTarget2 = 1; protected Unit unit; protected Interval timer = new Interval(4); @@ -27,6 +28,7 @@ public class AIController implements UnitController{ { timer.reset(0, Mathf.random(40f)); + timer.reset(1, Mathf.random(60f)); } @Override diff --git a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java index 752528970b..23d742a080 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/LiquidTurret.java @@ -108,7 +108,7 @@ public class LiquidTurret extends Turret{ public BulletType useAmmo(){ if(cheating()) return 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; } @@ -119,7 +119,7 @@ public class LiquidTurret extends Turret{ @Override 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 @@ -131,7 +131,7 @@ public class LiquidTurret extends Turret{ public boolean acceptLiquid(Building source, Liquid liquid, float amount){ return ammoTypes.get(liquid) != null && (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)); } } }