Setup for RTS AI

This commit is contained in:
Anuken 2022-02-17 18:06:33 -05:00
parent 9f3af412f0
commit aaba579314
12 changed files with 61 additions and 30 deletions

View File

@ -1052,6 +1052,7 @@ rules.wavetimer = Wave Timer
rules.waves = Waves
rules.attack = Attack Mode
rules.buildai = AI Building
rules.rtsai = RTS AI
rules.aitier = AI Tier
rules.cleanupdeadteams = Clean Up Defeated Team Buildings (PvP)
rules.corecapture = Capture Core On Destruction

View File

@ -36,8 +36,8 @@ public class BaseAI{
private int lastX, lastY, lastW, lastH;
private boolean triedWalls, foundPath;
TeamData data;
Interval timer = new Interval(4);
final TeamData data;
final Interval timer = new Interval(4);
IntSet path = new IntSet();
IntSet calcPath = new IntSet();

View File

@ -0,0 +1,15 @@
package mindustry.ai;
import mindustry.game.Teams.*;
public class RtsAI{
final TeamData data;
public RtsAI(TeamData data){
this.data = data;
}
public void update(){
}
}

View File

@ -583,7 +583,7 @@ public class UnitTypes{
//region ground legs
crawler = new UnitType("crawler"){{
defaultController = SuicideAI::new;
aiController = SuicideAI::new;
speed = 1f;
hitSize = 8f;
@ -1236,7 +1236,7 @@ public class UnitTypes{
//region air support
mono = new UnitType("mono"){{
unitBasedDefaultController = u -> new MinerAI();
defaultController = u -> new MinerAI();
flying = true;
drag = 0.06f;
@ -1255,7 +1255,7 @@ public class UnitTypes{
}};
poly = new UnitType("poly"){{
unitBasedDefaultController = u -> new BuilderAI();
defaultController = u -> new BuilderAI();
flying = true;
drag = 0.05f;
@ -1311,7 +1311,7 @@ public class UnitTypes{
mega = new UnitType("mega"){{
//TODO control?
defaultController = RepairAI::new;
aiController = RepairAI::new;
mineTier = 3;
mineSpeed = 4f;
@ -1435,7 +1435,7 @@ public class UnitTypes{
}};
oct = new UnitType("oct"){{
defaultController = DefenderAI::new;
aiController = DefenderAI::new;
armor = 16f;
health = 24000;
@ -2301,7 +2301,7 @@ public class UnitTypes{
//region core
alpha = new UnitType("alpha"){{
defaultController = BuilderAI::new;
aiController = BuilderAI::new;
isCounted = false;
lowAltitude = true;
@ -2338,7 +2338,7 @@ public class UnitTypes{
}};
beta = new UnitType("beta"){{
defaultController = BuilderAI::new;
aiController = BuilderAI::new;
isCounted = false;
flying = true;
@ -2379,7 +2379,7 @@ public class UnitTypes{
}};
gamma = new UnitType("gamma"){{
defaultController = BuilderAI::new;
aiController = BuilderAI::new;
isCounted = false;
lowAltitude = true;
@ -2922,7 +2922,7 @@ public class UnitTypes{
//region erekir - flying
quell = new ErekirUnitType("quell"){{
defaultController = FlyingFollowAI::new;
aiController = FlyingFollowAI::new;
envDisabled = 0;
lowAltitude = false;
@ -2988,7 +2988,7 @@ public class UnitTypes{
}};
disrupt = new ErekirUnitType("disrupt"){{
defaultController = FlyingFollowAI::new;
aiController = FlyingFollowAI::new;
envDisabled = 0;
lowAltitude = false;
@ -3157,7 +3157,7 @@ public class UnitTypes{
//TODO bad name
evoke = new ErekirUnitType("evoke"){{
coreUnitDock = true;
defaultController = BuilderAI::new;
aiController = BuilderAI::new;
isCounted = false;
envDisabled = 0;
@ -3214,7 +3214,7 @@ public class UnitTypes{
incite = new ErekirUnitType("incite"){{
coreUnitDock = true;
defaultController = BuilderAI::new;
aiController = BuilderAI::new;
isCounted = false;
envDisabled = 0;
@ -3283,7 +3283,7 @@ public class UnitTypes{
emanate = new ErekirUnitType("emanate"){{
coreUnitDock = true;
defaultController = BuilderAI::new;
aiController = BuilderAI::new;
isCounted = false;
envDisabled = 0;
@ -3355,7 +3355,7 @@ public class UnitTypes{
}};
manifold = new ErekirUnitType("manifold"){{
defaultController = CargoAI::new;
aiController = CargoAI::new;
isCounted = false;
allowedInPayloads = false;
logicControllable = false;
@ -3382,7 +3382,7 @@ public class UnitTypes{
}};
assemblyDrone = new ErekirUnitType("assembly-drone"){{
defaultController = AssemblerAI::new;
aiController = AssemblerAI::new;
flying = true;
drag = 0.06f;

View File

@ -3,6 +3,7 @@ package mindustry.core;
import arc.*;
import arc.math.*;
import arc.util.*;
import mindustry.ai.*;
import mindustry.annotations.Annotations.*;
import mindustry.core.GameState.*;
import mindustry.ctype.*;
@ -415,7 +416,13 @@ public class Logic implements ApplicationListener{
for(TeamData data : state.teams.getActive()){
if(data.hasAI()){
data.ai.update();
if(data.baseAi == null) data.baseAi = new BaseAI(data);
data.baseAi.update();
}
if(data.team.rules().rtsAi){
if(data.rtsAi == null) data.rtsAi = new RtsAI(data);
data.rtsAi.update();
}
}
}

View File

@ -201,7 +201,7 @@ public class Rules{
/** A team-specific ruleset. */
public static class TeamRule{
/** Whether to use building AI. */
/** Whether to use building AI. TODO remove, it is terrible. */
public boolean ai;
/** TODO Tier of blocks/designs that the AI uses for building. [0, 1] */
public float aiTier = 1f;
@ -214,6 +214,9 @@ public class Rules{
/** If true, this team has infinite unit ammo. */
public boolean infiniteAmmo;
/** Enables "RTS" unit AI. TODO wip */
public boolean rtsAi;
/** How fast unit factories build units. */
public float unitBuildSpeedMultiplier = 1f;
/** How much damage any other units deal. */

View File

@ -222,7 +222,11 @@ public class Teams{
public static class TeamData{
public final Seq<CoreBuild> cores = new Seq<>();
public final Team team;
public final BaseAI ai;
/** Handles building ""bases"". */
public @Nullable BaseAI baseAi;
/** Handles RTS unit control. */
public @Nullable RtsAI rtsAi;
private boolean presentFlag;
@ -248,7 +252,6 @@ public class Teams{
public TeamData(Team team){
this.team = team;
this.ai = new BaseAI(this);
}
/** Destroys this team's presence on the map, killing part of its buildings and converting everything to 'derelict'. */

View File

@ -454,13 +454,13 @@ public class ContentParser{
}
if(value.has("controller")){
unit.defaultController = supply(resolve(value.getString("controller"), FlyingAI.class));
unit.aiController = supply(resolve(value.getString("controller"), FlyingAI.class));
value.remove("controller");
}
if(value.has("unitBasedController")){
unit.unitBasedDefaultController = u -> supply(resolve(value.getString("unitBasedController"), FlyingAI.class)).get();
value.remove("unitBasedController");
if(value.has("defaultController")){
unit.defaultController = u -> supply(resolve(value.getString("defaultController"), FlyingAI.class)).get();
value.remove("defaultController");
}
//read extra default waves

View File

@ -114,10 +114,10 @@ public class UnitType extends UnlockableContent{
//TODO different names for these fields.
/** The default AI controller to assign on creation. */
public Prov<? extends UnitController> defaultController = () -> !flying ? new GroundAI() : new FlyingAI();
public Prov<? extends UnitController> aiController = () -> !flying ? new GroundAI() : new FlyingAI();
/** Function that chooses AI controller based on unit entity. */
//TODO -name is too long
public Func<Unit, ? extends UnitController> unitBasedDefaultController = u -> !playerControllable || u.team.isAI() ? defaultController.get() : new CommandAI();
public Func<Unit, ? extends UnitController> defaultController = u -> !playerControllable || (u.team.isAI() && !u.team.rules().rtsAi) ? aiController.get() : new CommandAI();
public Color outlineColor = Pal.darkerMetal;
public int outlineRadius = 3;
@ -218,7 +218,7 @@ public class UnitType extends UnlockableContent{
}
public UnitController createController(Unit unit){
return unitBasedDefaultController.get(unit);
return defaultController.get(unit);
}
public Unit create(Team team){

View File

@ -19,7 +19,7 @@ public class MissileUnitType extends UnitType{
isCounted = false;
useUnitCap = false;
allowedInPayloads = false;
defaultController = MissileAI::new;
aiController = MissileAI::new;
flying = true;
constructor = TimedKillUnit::create;
envEnabled = Env.any;

View File

@ -235,6 +235,8 @@ public class CustomRulesDialog extends BaseDialog{
number("@rules.blockhealthmultiplier", f -> teams.blockHealthMultiplier = f, () -> teams.blockHealthMultiplier);
number("@rules.blockdamagemultiplier", f -> teams.blockDamageMultiplier = f, () -> teams.blockDamageMultiplier);
check("@rules.rtsai", b -> teams.rtsAi = b, () -> teams.rtsAi, () -> team != rules.defaultTeam);
check("@rules.buildai", b -> teams.ai = b, () -> teams.ai, () -> team != rules.defaultTeam);
number("@rules.aitier", false, f -> teams.aiTier = f, () -> teams.aiTier, () -> teams.ai, 0, 1);

View File

@ -34,7 +34,7 @@ public class DroneCenter extends Block{
public void init(){
super.init();
droneType.defaultController = EffectDroneAI::new;
droneType.aiController = EffectDroneAI::new;
}
public class DroneCenterBuild extends Building{