mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-15 10:17:39 +07:00
Misc RTS AI intelligence fixes
This commit is contained in:
@ -9,6 +9,7 @@ import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ai.types.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.game.Teams.*;
|
||||
@ -107,7 +108,7 @@ public class RtsAI{
|
||||
boolean didDefend = false;
|
||||
|
||||
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();
|
||||
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
|
||||
//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;
|
||||
|
||||
if(debug){
|
||||
@ -197,7 +198,7 @@ public class RtsAI{
|
||||
Vec2 defendPos = null;
|
||||
Teamc defendTarget = null;
|
||||
if(defend != null){
|
||||
float checkRange = 260f;
|
||||
float checkRange = 350f;
|
||||
|
||||
//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));
|
||||
@ -205,6 +206,7 @@ public class RtsAI{
|
||||
//do not target it directly - target the position?
|
||||
//defendTarget = aggressor;
|
||||
defendPos = new Vec2(aggressor.x, aggressor.y);
|
||||
defendTarget = aggressor;
|
||||
}else if(false){ //TODO currently ignored, no use defending against nothing
|
||||
//should it even go there if there's no aggressor found?
|
||||
Tile closest = defend.findClosestEdge(units.first(), Tile::solid);
|
||||
@ -247,7 +249,7 @@ public class RtsAI{
|
||||
if(build != null || anyDefend){
|
||||
for(var unit : units){
|
||||
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);
|
||||
}else{
|
||||
//TODO stopAtTarget parameter could be false, could be tweaked
|
||||
|
@ -6,6 +6,7 @@ import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.units.*;
|
||||
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
|
||||
public void updateUnit(){
|
||||
|
||||
@ -139,7 +144,7 @@ public class CommandAI extends AIController{
|
||||
move = Vars.controlPath.getPathPosition(unit, pathId, targetPos, vecOut, noFound);
|
||||
|
||||
//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){
|
||||
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;
|
||||
stopWhenInRange = false;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class ErekirTechTree{
|
||||
costMultipliers.put(Items.graphite, 9);
|
||||
//oxide is hard to make
|
||||
costMultipliers.put(Items.oxide, 0.5f);
|
||||
costMultipliers.put(Items.carbide, 0.6f);
|
||||
costMultipliers.put(Items.carbide, 0.4f);
|
||||
|
||||
//TODO remove
|
||||
Objective tmpNever = new Research(Items.fissileMatter);
|
||||
|
@ -2666,7 +2666,7 @@ public class UnitTypes{
|
||||
heatColor = Color.valueOf("f9350f");
|
||||
cooldownTime = 80f;
|
||||
|
||||
bullet = new BasicBulletType(8f, 150){{
|
||||
bullet = new BasicBulletType(8f, 160){{
|
||||
sprite = "missile-large";
|
||||
width = 9.5f;
|
||||
height = 13f;
|
||||
@ -3254,7 +3254,7 @@ public class UnitTypes{
|
||||
drag = 0.1f;
|
||||
speed = 0.6f;
|
||||
hitSize = 23f;
|
||||
health = 7000;
|
||||
health = 6700;
|
||||
armor = 5f;
|
||||
|
||||
lockLegBase = true;
|
||||
@ -3315,7 +3315,7 @@ public class UnitTypes{
|
||||
velocityRnd = 0.33f;
|
||||
heatColor = Color.red;
|
||||
|
||||
bullet = new MissileBulletType(4.2f, 50){{
|
||||
bullet = new MissileBulletType(4.2f, 47){{
|
||||
homingPower = 0.2f;
|
||||
weaveMag = 4;
|
||||
weaveScale = 4;
|
||||
@ -3839,7 +3839,7 @@ public class UnitTypes{
|
||||
rotateSpeed = 2f;
|
||||
accel = 0.1f;
|
||||
health = 12000f;
|
||||
armor = 7f;
|
||||
armor = 9f;
|
||||
hitSize = 46f;
|
||||
payloadCapacity = Mathf.sqr(6f) * tilePayload;
|
||||
|
||||
|
@ -77,7 +77,6 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
rotateMove(movement);
|
||||
}
|
||||
}
|
||||
|
||||
public void moveAt(Vec2 vector){
|
||||
moveAt(vector, type.accel);
|
||||
}
|
||||
@ -85,7 +84,6 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
public void approach(Vec2 vector){
|
||||
vel.approachDelta(vector, type.accel * speed());
|
||||
}
|
||||
|
||||
public void rotateMove(Vec2 vec){
|
||||
moveAt(Tmp.v2.trns(rotation, vec.len()));
|
||||
|
||||
@ -104,6 +102,11 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
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 */
|
||||
public float physicSize(){
|
||||
return hitSize * 0.7f;
|
||||
|
@ -25,4 +25,4 @@ org.gradle.caching=true
|
||||
#used for slow jitpack builds; TODO see if this actually works
|
||||
org.gradle.internal.http.socketTimeout=100000
|
||||
org.gradle.internal.http.connectionTimeout=100000
|
||||
archash=8793e01874
|
||||
archash=5a1cbb8b59
|
||||
|
Reference in New Issue
Block a user