From 876534bd26accd13a1e12100321a08c19426853a Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 12 Oct 2020 14:33:22 -0400 Subject: [PATCH] Wave balancing & AI tweaks --- core/src/mindustry/ai/types/BuilderAI.java | 24 +++++++++++++++-- core/src/mindustry/ai/types/RepairAI.java | 27 +++++++++++++------ core/src/mindustry/content/UnitTypes.java | 2 +- .../entities/units/AIController.java | 17 ++++++++++++ core/src/mindustry/game/DefaultWaves.java | 25 ++++++++++++----- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index 1e1875e176..8e8c74f986 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -17,13 +17,17 @@ public class BuilderAI extends AIController{ @Nullable Builderc following; @Override - public void updateUnit(){ + public void updateMovement(){ Builderc builder = (Builderc)unit; if(builder.moving()){ builder.lookAt(builder.vel().angle()); } + if(target != null && shouldShoot()){ + unit.lookAt(target); + } + builder.updateBuilding(true); if(following != null){ @@ -95,13 +99,29 @@ public class BuilderAI extends AIController{ }else if(Build.validPlace(content.block(block.block), unit.team(), block.x, block.y, block.rotation)){ //it's valid. //add build request. builder.addBuild(new BuildPlan(block.x, block.y, block.rotation, content.block(block.block), block.config)); + //shift build plan to tail so next unit builds something else. + blocks.addLast(blocks.removeFirst()); }else{ //shift head of queue to tail, try something else next time blocks.removeFirst(); blocks.addLast(block); } } - } } + + @Override + public AIController fallback(){ + return unit.type().flying ? new FlyingAI() : new GroundAI(); + } + + @Override + public boolean useFallback(){ + return state.rules.waves && unit.team == state.rules.waveTeam && !unit.team.rules().ai; + } + + @Override + public boolean shouldShoot(){ + return !((Builderc)unit).isBuilding(); + } } diff --git a/core/src/mindustry/ai/types/RepairAI.java b/core/src/mindustry/ai/types/RepairAI.java index 84baf1c555..5f021ae828 100644 --- a/core/src/mindustry/ai/types/RepairAI.java +++ b/core/src/mindustry/ai/types/RepairAI.java @@ -2,27 +2,33 @@ package mindustry.ai.types; import mindustry.entities.*; import mindustry.entities.units.*; +import mindustry.gen.*; import mindustry.world.blocks.ConstructBlock.*; -//note that repair AI doesn't attack anything even if it theoretically can public class RepairAI extends AIController{ @Override protected void updateMovement(){ - boolean shoot = false; - - if(target != null){ - if(!target.within(unit, unit.type().range * 0.8f)){ - moveTo(target, unit.type().range * 0.8f); - } + if(target instanceof Building){ + boolean shoot = false; if(target.within(unit, unit.type().range)){ unit.aim(target); shoot = true; } + + unit.controlWeapons(shoot); + }else if(target == null){ + unit.controlWeapons(false); } - unit.controlWeapons(shoot); + if(target != null){ + if(!target.within(unit, unit.type().range * 0.65f)){ + moveTo(target, unit.type().range * 0.65f); + } + + unit.lookAt(target); + } } @Override @@ -30,5 +36,10 @@ public class RepairAI extends AIController{ target = Units.findDamagedTile(unit.team, unit.x, unit.y); if(target instanceof ConstructBuild) target = null; + + if(target == null){ + super.updateTargeting(); + } } + } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 7474168ef6..9a1b851118 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -1145,7 +1145,7 @@ public class UnitTypes implements ContentList{ speed = 1.9f; rotateSpeed = 15f; accel = 0.1f; - range = 70f; + range = 130f; health = 400; buildSpeed = 0.5f; engineOffset = 6.5f; diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index d235972212..b02fa5dc00 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -21,6 +21,7 @@ public class AIController implements UnitController{ protected Unit unit; protected Interval timer = new Interval(4); + protected AIController fallback; /** main target that is being faced */ protected Teamc target; @@ -34,11 +35,27 @@ public class AIController implements UnitController{ @Override public void updateUnit(){ + //use fallback AI when possible + if(useFallback() && (fallback != null || (fallback = fallback()) != null)){ + if(fallback.unit != unit) fallback.unit(unit); + fallback.updateUnit(); + return; + } + updateVisuals(); updateTargeting(); updateMovement(); } + @Nullable + protected AIController fallback(){ + return null; + } + + protected boolean useFallback(){ + return false; + } + protected UnitCommand command(){ return unit.team.data().command; } diff --git a/core/src/mindustry/game/DefaultWaves.java b/core/src/mindustry/game/DefaultWaves.java index bc03b29e0f..53a0bfa99c 100644 --- a/core/src/mindustry/game/DefaultWaves.java +++ b/core/src/mindustry/game/DefaultWaves.java @@ -119,6 +119,7 @@ public class DefaultWaves{ unitAmount = 2; unitScaling = 2; max = 20; + shieldScaling = 30; }}, new SpawnGroup(dagger){{ @@ -144,6 +145,7 @@ public class DefaultWaves{ unitAmount = 2; spacing = 2; unitScaling = 2; + shieldScaling = 20; }}, new SpawnGroup(flare){{ @@ -162,6 +164,7 @@ public class DefaultWaves{ unitScaling = 3; spacing = 5; max = 16; + shieldScaling = 30; }}, new SpawnGroup(nova){{ @@ -169,6 +172,7 @@ public class DefaultWaves{ unitAmount = 2; unitScaling = 3; spacing = 4; + shieldScaling = 20; }}, new SpawnGroup(atrax){{ @@ -192,15 +196,15 @@ public class DefaultWaves{ unitAmount = 1; unitScaling = 1; spacing = 40; - shieldScaling = 10f; + shieldScaling = 20f; }}, new SpawnGroup(antumbra){{ - begin = 131; + begin = 120; unitAmount = 1; unitScaling = 1; spacing = 40; - shieldScaling = 10f; + shieldScaling = 20f; }}, new SpawnGroup(vela){{ @@ -211,6 +215,15 @@ public class DefaultWaves{ shieldScaling = 20f; }}, + new SpawnGroup(corvus){{ + begin = 145; + unitAmount = 1; + unitScaling = 1; + spacing = 35; + shieldScaling = 30f; + shields = 100; + }}, + new SpawnGroup(horizon){{ begin = 90; unitAmount = 2; @@ -252,7 +265,7 @@ public class DefaultWaves{ //max reasonable wave, after which everything gets boring int cap = 200; - float shieldStart = 30, shieldsPerWave = 15 + difficulty*20f; + float shieldStart = 30, shieldsPerWave = 20 + difficulty*30f; Intc createProgression = start -> { //main sequence @@ -314,8 +327,8 @@ public class DefaultWaves{ step += (int)(Mathf.random(12, 25) * Mathf.lerp(1f, 0.4f, difficulty)); } - int bossWave = Mathf.random(30, 60); - int bossSpacing = Mathf.random(30, 50); + int bossWave = (int)(Mathf.random(30, 60) * Mathf.lerp(1f, 0.7f, difficulty)); + int bossSpacing = (int)(Mathf.random(25, 40) * Mathf.lerp(1f, 0.6f, difficulty)); //main boss progression out.add(new SpawnGroup(Structs.random(species)[4]){{