Campaign rule for unpredictable wave AI
This commit is contained in:
@@ -1399,6 +1399,7 @@ rules.lighting = Lighting
|
|||||||
rules.fog = Fog of War
|
rules.fog = Fog of War
|
||||||
rules.invasions = Enemy Sector Invasions
|
rules.invasions = Enemy Sector Invasions
|
||||||
rules.showspawns = Show Enemy Spawns
|
rules.showspawns = Show Enemy Spawns
|
||||||
|
rules.randomwaveai = Unpredictable Wave AI
|
||||||
rules.fire = Fire
|
rules.fire = Fire
|
||||||
rules.anyenv = <Any>
|
rules.anyenv = <Any>
|
||||||
rules.explosions = Block/Unit Explosion Damage
|
rules.explosions = Block/Unit Explosion Damage
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mindustry.ai;
|
|||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -16,6 +17,7 @@ import mindustry.world.blocks.storage.*;
|
|||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
import static mindustry.world.meta.BlockFlag.*;
|
||||||
|
|
||||||
public class Pathfinder implements Runnable{
|
public class Pathfinder implements Runnable{
|
||||||
private static final long maxUpdate = Time.millisToNanos(8);
|
private static final long maxUpdate = Time.millisToNanos(8);
|
||||||
@@ -454,8 +456,28 @@ public class Pathfinder implements Runnable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class EnemyCoreField extends Flowfield{
|
public static class EnemyCoreField extends Flowfield{
|
||||||
|
private final static BlockFlag[] randomTargets = {storage, generator, launchPad, factory, repair, battery, reactor, drill};
|
||||||
|
private Rand rand = new Rand();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void getPositions(IntSeq out){
|
protected void getPositions(IntSeq out){
|
||||||
|
if(state.rules.randomWaveAI && team == state.rules.waveTeam){
|
||||||
|
rand.setSeed(state.rules.waves ? state.wave : (int)(state.tick / (5400)));
|
||||||
|
|
||||||
|
//maximum amount of different target flag types they will attack
|
||||||
|
int max = 2;
|
||||||
|
|
||||||
|
for(int attempt = 0; attempt < 5 && max > 0; attempt++){
|
||||||
|
var targets = indexer.getEnemy(team, randomTargets[rand.random(randomTargets.length - 1)]);
|
||||||
|
if(!targets.isEmpty()){
|
||||||
|
max --;
|
||||||
|
for(Building other : targets){
|
||||||
|
out.add(other.tile.array());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(Building other : indexer.getEnemy(team, BlockFlag.core)){
|
for(Building other : indexer.getEnemy(team, BlockFlag.core)){
|
||||||
out.add(other.tile.array());
|
out.add(other.tile.array());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class FlyingAI extends AIController{
|
|||||||
return core;
|
return core;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state.rules.randomAirTargeting){
|
if(state.rules.randomWaveAI){
|
||||||
//when there are no waves, it's just random based on the unit
|
//when there are no waves, it's just random based on the unit
|
||||||
Mathf.rand.setSeed(unit.type.id + (state.rules.waves ? state.wave : unit.id));
|
Mathf.rand.setSeed(unit.type.id + (state.rules.waves ? state.wave : unit.id));
|
||||||
//try a few random flags first
|
//try a few random flags first
|
||||||
@@ -56,17 +56,15 @@ public class FlyingAI extends AIController{
|
|||||||
//try the closest target
|
//try the closest target
|
||||||
Teamc result = target(x, y, range, air, ground);
|
Teamc result = target(x, y, range, air, ground);
|
||||||
if(result != null) return result;
|
if(result != null) return result;
|
||||||
//default to the core
|
}else{
|
||||||
return core;
|
for(var flag : unit.type.targetFlags){
|
||||||
}
|
if(flag == null){
|
||||||
|
Teamc result = target(x, y, range, air, ground);
|
||||||
for(var flag : unit.type.targetFlags){
|
if(result != null) return result;
|
||||||
if(flag == null){
|
}else if(ground){
|
||||||
Teamc result = target(x, y, range, air, ground);
|
Teamc result = targetFlag(x, y, flag, true);
|
||||||
if(result != null) return result;
|
if(result != null) return result;
|
||||||
}else if(ground){
|
}
|
||||||
Teamc result = targetFlag(x, y, flag, true);
|
|
||||||
if(result != null) return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ public class CampaignRules{
|
|||||||
public boolean fog;
|
public boolean fog;
|
||||||
public boolean showSpawns;
|
public boolean showSpawns;
|
||||||
public boolean sectorInvasion;
|
public boolean sectorInvasion;
|
||||||
|
public boolean randomWaveAI;
|
||||||
|
|
||||||
public void apply(Rules rules){
|
public void apply(Rules rules){
|
||||||
rules.staticFog = rules.fog = fog;
|
rules.staticFog = rules.fog = fog;
|
||||||
rules.showSpawns = showSpawns;
|
rules.showSpawns = showSpawns;
|
||||||
|
rules.randomWaveAI = randomWaveAI;
|
||||||
rules.teams.get(rules.waveTeam).blockHealthMultiplier = difficulty.enemyHealthMultiplier;
|
rules.teams.get(rules.waveTeam).blockHealthMultiplier = difficulty.enemyHealthMultiplier;
|
||||||
rules.teams.get(rules.waveTeam).unitHealthMultiplier = difficulty.enemyHealthMultiplier;
|
rules.teams.get(rules.waveTeam).unitHealthMultiplier = difficulty.enemyHealthMultiplier;
|
||||||
rules.randomAirTargeting = difficulty.ordinal() >= Difficulty.hard.ordinal();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ public class Rules{
|
|||||||
public boolean fire = true;
|
public boolean fire = true;
|
||||||
/** Whether units use and require ammo. */
|
/** Whether units use and require ammo. */
|
||||||
public boolean unitAmmo = false;
|
public boolean unitAmmo = false;
|
||||||
/** EXPERIMENTAL! If true, air units target random things each wave instead of only generators. */
|
/** EXPERIMENTAL! If true, air and ground units target random things each wave instead of only the core/generators. */
|
||||||
public boolean randomAirTargeting = false;
|
public boolean randomWaveAI = false;
|
||||||
/** EXPERIMENTAL! If true, blocks will update in units and share power. */
|
/** EXPERIMENTAL! If true, blocks will update in units and share power. */
|
||||||
public boolean unitPayloadUpdate = false;
|
public boolean unitPayloadUpdate = false;
|
||||||
/** If true, units' payloads are destroy()ed when the unit is destroyed. */
|
/** If true, units' payloads are destroy()ed when the unit is destroyed. */
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ public class CampaignRulesDialog extends BaseDialog{
|
|||||||
|
|
||||||
check("@rules.fog", b -> rules.fog = b, () -> rules.fog);
|
check("@rules.fog", b -> rules.fog = b, () -> rules.fog);
|
||||||
check("@rules.showspawns", b -> rules.showSpawns = b, () -> rules.showSpawns);
|
check("@rules.showspawns", b -> rules.showSpawns = b, () -> rules.showSpawns);
|
||||||
|
check("@rules.randomwaveai", b -> rules.randomWaveAI = b, () -> rules.randomWaveAI);
|
||||||
}).growY();
|
}).growY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user