Misc RTS AI intelligence fixes
This commit is contained in:
@@ -9,6 +9,7 @@ import arc.util.*;
|
|||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.ai.types.*;
|
import mindustry.ai.types.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.core.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
@@ -107,7 +108,7 @@ public class RtsAI{
|
|||||||
boolean didDefend = false;
|
boolean didDefend = false;
|
||||||
|
|
||||||
for(var unit : data.units){
|
for(var unit : data.units){
|
||||||
if(unit.isCommandable() && !unit.command().hasCommand() && used.add(unit.id)){
|
if(used.add(unit.id) && unit.isCommandable() && !unit.command().hasCommand() && !unit.command().isAttacking()){
|
||||||
squad.clear();
|
squad.clear();
|
||||||
data.tree().intersect(unit.x - squadRadius/2f, unit.y - squadRadius/2f, squadRadius, squadRadius, squad);
|
data.tree().intersect(unit.x - squadRadius/2f, unit.y - squadRadius/2f, squadRadius, squadRadius, squad);
|
||||||
|
|
||||||
@@ -178,7 +179,7 @@ public class RtsAI{
|
|||||||
|
|
||||||
//defend when close, or this is the only squad defending
|
//defend when close, or this is the only squad defending
|
||||||
//TODO will always rush to defense no matter what
|
//TODO will always rush to defense no matter what
|
||||||
if(best != null && (best instanceof CoreBuild || (units.size >= data.team.rules().rtsMinSquad || (units.size > 0 && units.first().flag != 0)) || best.within(ax, ay, 500f))){
|
if(best != null && (best instanceof CoreBuild || (units.size >= data.team.rules().rtsMinSquad || (units.size > 0 && units.first().flag != 0)) || best.within(ax, ay, 1000f))){
|
||||||
defend = best;
|
defend = best;
|
||||||
|
|
||||||
if(debug){
|
if(debug){
|
||||||
@@ -197,7 +198,7 @@ public class RtsAI{
|
|||||||
Vec2 defendPos = null;
|
Vec2 defendPos = null;
|
||||||
Teamc defendTarget = null;
|
Teamc defendTarget = null;
|
||||||
if(defend != null){
|
if(defend != null){
|
||||||
float checkRange = 260f;
|
float checkRange = 350f;
|
||||||
|
|
||||||
//TODO could be made faster by storing bullet shooter
|
//TODO could be made faster by storing bullet shooter
|
||||||
Unit aggressor = Units.closestEnemy(data.team, defend.x, defend.y, checkRange, u -> u.checkTarget(tair, tground));
|
Unit aggressor = Units.closestEnemy(data.team, defend.x, defend.y, checkRange, u -> u.checkTarget(tair, tground));
|
||||||
@@ -205,6 +206,7 @@ public class RtsAI{
|
|||||||
//do not target it directly - target the position?
|
//do not target it directly - target the position?
|
||||||
//defendTarget = aggressor;
|
//defendTarget = aggressor;
|
||||||
defendPos = new Vec2(aggressor.x, aggressor.y);
|
defendPos = new Vec2(aggressor.x, aggressor.y);
|
||||||
|
defendTarget = aggressor;
|
||||||
}else if(false){ //TODO currently ignored, no use defending against nothing
|
}else if(false){ //TODO currently ignored, no use defending against nothing
|
||||||
//should it even go there if there's no aggressor found?
|
//should it even go there if there's no aggressor found?
|
||||||
Tile closest = defend.findClosestEdge(units.first(), Tile::solid);
|
Tile closest = defend.findClosestEdge(units.first(), Tile::solid);
|
||||||
@@ -247,7 +249,7 @@ public class RtsAI{
|
|||||||
if(build != null || anyDefend){
|
if(build != null || anyDefend){
|
||||||
for(var unit : units){
|
for(var unit : units){
|
||||||
if(unit.isCommandable() && !unit.command().hasCommand()){
|
if(unit.isCommandable() && !unit.command().hasCommand()){
|
||||||
if(defendPos != null){
|
if(defendPos != null && !unit.isPathImpassable(World.toTile(defendPos.x), World.toTile(defendPos.y))){
|
||||||
unit.command().commandPosition(defendPos, true);
|
unit.command().commandPosition(defendPos, true);
|
||||||
}else{
|
}else{
|
||||||
//TODO stopAtTarget parameter could be false, could be tweaked
|
//TODO stopAtTarget parameter could be false, could be tweaked
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.struct.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.ai.*;
|
import mindustry.ai.*;
|
||||||
|
import mindustry.core.*;
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
@@ -48,6 +49,10 @@ public class CommandAI extends AIController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAttacking(){
|
||||||
|
return target != null && unit.within(target, unit.range() + 10f);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUnit(){
|
public void updateUnit(){
|
||||||
|
|
||||||
@@ -139,7 +144,7 @@ public class CommandAI extends AIController{
|
|||||||
move = Vars.controlPath.getPathPosition(unit, pathId, targetPos, vecOut, noFound);
|
move = Vars.controlPath.getPathPosition(unit, pathId, targetPos, vecOut, noFound);
|
||||||
|
|
||||||
//if the path is invalid, stop trying and record the end as unreachable
|
//if the path is invalid, stop trying and record the end as unreachable
|
||||||
if(unit.team.isAI() && noFound[0]){
|
if(unit.team.isAI() && (noFound[0] || unit.isPathImpassable(World.toTile(targetPos.x), World.toTile(targetPos.y)) )){
|
||||||
if(attackTarget instanceof Building build){
|
if(attackTarget instanceof Building build){
|
||||||
unreachableBuildings.addUnique(build.pos());
|
unreachableBuildings.addUnique(build.pos());
|
||||||
}
|
}
|
||||||
@@ -194,7 +199,7 @@ public class CommandAI extends AIController{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stopWhenInRange && targetPos != null && unit.within(targetPos, engageRange - 1f)){
|
if(stopWhenInRange && targetPos != null && unit.within(targetPos, engageRange * 0.9f)){
|
||||||
targetPos = null;
|
targetPos = null;
|
||||||
stopWhenInRange = false;
|
stopWhenInRange = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class ErekirTechTree{
|
|||||||
costMultipliers.put(Items.graphite, 9);
|
costMultipliers.put(Items.graphite, 9);
|
||||||
//oxide is hard to make
|
//oxide is hard to make
|
||||||
costMultipliers.put(Items.oxide, 0.5f);
|
costMultipliers.put(Items.oxide, 0.5f);
|
||||||
costMultipliers.put(Items.carbide, 0.6f);
|
costMultipliers.put(Items.carbide, 0.4f);
|
||||||
|
|
||||||
//TODO remove
|
//TODO remove
|
||||||
Objective tmpNever = new Research(Items.fissileMatter);
|
Objective tmpNever = new Research(Items.fissileMatter);
|
||||||
|
|||||||
@@ -2666,7 +2666,7 @@ public class UnitTypes{
|
|||||||
heatColor = Color.valueOf("f9350f");
|
heatColor = Color.valueOf("f9350f");
|
||||||
cooldownTime = 80f;
|
cooldownTime = 80f;
|
||||||
|
|
||||||
bullet = new BasicBulletType(8f, 150){{
|
bullet = new BasicBulletType(8f, 160){{
|
||||||
sprite = "missile-large";
|
sprite = "missile-large";
|
||||||
width = 9.5f;
|
width = 9.5f;
|
||||||
height = 13f;
|
height = 13f;
|
||||||
@@ -3254,7 +3254,7 @@ public class UnitTypes{
|
|||||||
drag = 0.1f;
|
drag = 0.1f;
|
||||||
speed = 0.6f;
|
speed = 0.6f;
|
||||||
hitSize = 23f;
|
hitSize = 23f;
|
||||||
health = 7000;
|
health = 6700;
|
||||||
armor = 5f;
|
armor = 5f;
|
||||||
|
|
||||||
lockLegBase = true;
|
lockLegBase = true;
|
||||||
@@ -3315,7 +3315,7 @@ public class UnitTypes{
|
|||||||
velocityRnd = 0.33f;
|
velocityRnd = 0.33f;
|
||||||
heatColor = Color.red;
|
heatColor = Color.red;
|
||||||
|
|
||||||
bullet = new MissileBulletType(4.2f, 50){{
|
bullet = new MissileBulletType(4.2f, 47){{
|
||||||
homingPower = 0.2f;
|
homingPower = 0.2f;
|
||||||
weaveMag = 4;
|
weaveMag = 4;
|
||||||
weaveScale = 4;
|
weaveScale = 4;
|
||||||
@@ -3839,7 +3839,7 @@ public class UnitTypes{
|
|||||||
rotateSpeed = 2f;
|
rotateSpeed = 2f;
|
||||||
accel = 0.1f;
|
accel = 0.1f;
|
||||||
health = 12000f;
|
health = 12000f;
|
||||||
armor = 7f;
|
armor = 9f;
|
||||||
hitSize = 46f;
|
hitSize = 46f;
|
||||||
payloadCapacity = Mathf.sqr(6f) * tilePayload;
|
payloadCapacity = Mathf.sqr(6f) * tilePayload;
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
rotateMove(movement);
|
rotateMove(movement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveAt(Vec2 vector){
|
public void moveAt(Vec2 vector){
|
||||||
moveAt(vector, type.accel);
|
moveAt(vector, type.accel);
|
||||||
}
|
}
|
||||||
@@ -85,7 +84,6 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
public void approach(Vec2 vector){
|
public void approach(Vec2 vector){
|
||||||
vel.approachDelta(vector, type.accel * speed());
|
vel.approachDelta(vector, type.accel * speed());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rotateMove(Vec2 vec){
|
public void rotateMove(Vec2 vec){
|
||||||
moveAt(Tmp.v2.trns(rotation, vec.len()));
|
moveAt(Tmp.v2.trns(rotation, vec.len()));
|
||||||
|
|
||||||
@@ -104,6 +102,11 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
|||||||
lookAt(x, y);
|
lookAt(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPathImpassable(int tileX, int tileY){
|
||||||
|
return !type.flying && type.pathCost.getCost(team.id, pathfinder.get(tileX, tileY)) == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @return approx. square size of the physical hitbox for physics */
|
/** @return approx. square size of the physical hitbox for physics */
|
||||||
public float physicSize(){
|
public float physicSize(){
|
||||||
return hitSize * 0.7f;
|
return hitSize * 0.7f;
|
||||||
|
|||||||
+1
-1
@@ -25,4 +25,4 @@ org.gradle.caching=true
|
|||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
org.gradle.internal.http.socketTimeout=100000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
org.gradle.internal.http.connectionTimeout=100000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
archash=8793e01874
|
archash=5a1cbb8b59
|
||||||
|
|||||||
Reference in New Issue
Block a user