Flare AI changed

This commit is contained in:
Anuken
2025-11-15 23:04:08 -05:00
parent cc693f97b6
commit ed860e8395
10 changed files with 58 additions and 21 deletions

View File

@@ -270,7 +270,6 @@ public class CommandAI extends AIController{
Building targetBuild = world.buildWorld(targetPos.x, targetPos.y);
//TODO: should the unit stop when it finds a target?
if(
(hasStance(UnitStance.patrol) && !hasStance(UnitStance.pursueTarget) && target != null && unit.within(target, unit.type.range - 2f) && !unit.type.circleTarget) ||
@@ -347,7 +346,7 @@ public class CommandAI extends AIController{
if(move){
if(unit.type.circleTarget && attackTarget != null){
target = attackTarget;
circleAttack(80f);
circleAttack(unit.type.circleTargetRadius);
}else{
moveTo(vecOut,
withinAttackRange ? engageRange :
@@ -362,7 +361,7 @@ public class CommandAI extends AIController{
attackTarget = null;
}
if(unit.isFlying() && move && (attackTarget == null || !unit.within(attackTarget, unit.type.range))){
if(unit.isFlying() && move && !(unit.type.circleTarget && !unit.type.omniMovement) && (attackTarget == null || !unit.within(attackTarget, unit.type.range))){
unit.lookAt(vecMovePos);
}else{
faceTarget();
@@ -379,7 +378,11 @@ public class CommandAI extends AIController{
}
}else if(target != null){
faceTarget();
if(unit.type.circleTarget && shouldFire()){
circleAttack(unit.type.circleTargetRadius);
}else{
faceTarget();
}
}
}

View File

@@ -19,7 +19,7 @@ public class FlyingAI extends AIController{
if(target != null && unit.hasWeapons()){
if(unit.type.circleTarget){
circleAttack(120f);
circleAttack(unit.type.circleTargetRadius);
}else{
moveTo(target, unit.type.range * 0.8f);
unit.lookAt(target);

View File

@@ -30,7 +30,7 @@ public class RepairAI extends AIController{
if(target != null && target instanceof Building b && b.team == unit.team){
if(unit.type.circleTarget){
circleAttack(120f);
circleAttack(unit.type.circleTargetRadius);
}else if(!target.within(unit, unit.type.range * 0.65f)){
moveTo(target, unit.type.range * 0.65f);
}

View File

@@ -995,18 +995,25 @@ public class UnitTypes{
flying = true;
health = 70;
engineOffset = 5.75f;
//TODO balance
//targetAir = false;
targetFlags = new BlockFlag[]{BlockFlag.generator, null};
hitSize = 9;
itemCapacity = 10;
circleTarget = true;
omniMovement = false;
rotateSpeed = 5f;
circleTargetRadius = 60f;
weapons.add(new Weapon(){{
y = 0f;
x = 2f;
reload = 20f;
y = 1f;
x = 0f;
minShootVelocity = 2f;
shootCone = 10f;
reload = 80f;
shoot.shots = 3;
shoot.shotDelay = 3f;
ejectEffect = Fx.casing1;
bullet = new BasicBulletType(2.5f, 9){{
mirror = false;
bullet = new BasicBulletType(2.5f, 15){{
width = 7f;
height = 9f;
lifetime = 45f;
@@ -1014,7 +1021,7 @@ public class UnitTypes{
smokeEffect = Fx.shootSmallSmoke;
ammoMultiplier = 2;
}};
shootSound = Sounds.pew;
shootSound = Sounds.shootDagger;
}});
}};
@@ -1035,9 +1042,12 @@ public class UnitTypes{
targetFlags = new BlockFlag[]{BlockFlag.factory, null};
circleTarget = true;
ammoType = new ItemAmmoType(Items.graphite);
omniMovement = false;
rotateSpeed = 4.5f;
circleTargetRadius = 40f;
weapons.add(new Weapon(){{
minShootVelocity = 0.75f;
minShootVelocity = 1f;
x = 3f;
shootY = 0f;
reload = 12f;

View File

@@ -44,7 +44,7 @@ public class GameState{
/** Team data. Gets reset every new game. */
public Teams teams = new Teams();
/** Handles JSON edits of game content. */
public ContentPatcher patcher = new ContentPatcher();
public DataPatcher patcher = new DataPatcher();
/** Number of enemies in the game; only used clientside in servers. */
public int enemies;
/** Map being playtested (not edited!) */

View File

@@ -98,7 +98,7 @@ public class RegionPart extends DrawPart{
int i = params.sideOverride == -1 ? s : params.sideOverride;
//can be null
var region = drawRegion ? regions[Math.min(i, regions.length - 1)] : null;
var region = drawRegion && regions.length > 0 ? regions[Math.min(i, regions.length - 1)] : null;
float sign = (i == 0 ? 1 : -1) * params.sideMultiplier;
Tmp.v1.set((x + mx) * sign, y + my).rotateRadExact((params.rotation - 90) * Mathf.degRad);

View File

@@ -28,6 +28,7 @@ public class AIController implements UnitController{
/** main target that is being faced */
protected @Nullable Teamc target;
protected @Nullable Teamc bomberTarget;
protected boolean turningAway;
{
resetTimers();
@@ -155,7 +156,8 @@ public class AIController implements UnitController{
}
public void targetInvalidated(){
//TODO: try this for normal units, reset the target timer
//immediately find a new target
timer.reset(timerTarget, -1f);
}
public void updateWeapons(){
@@ -169,7 +171,7 @@ public class AIController implements UnitController{
noTargetTime += Time.delta;
if(invalid(target)){
if(target != null && !target.isAdded()){
if(target instanceof Healthc h && !h.isValid()){
targetInvalidated();
}
target = null;
@@ -300,14 +302,32 @@ public class AIController implements UnitController{
}
public void circleAttack(float circleLength){
if(target == null) return;
vec.set(target).sub(unit);
float ang = unit.angleTo(target);
float diff = Angles.angleDist(ang, unit.rotation());
if(target instanceof Unit u && u.collisionLayer() == unit.collisionLayer()){
float avoidDist = u.physicSize() + 30f;
if(turningAway){
vec.setLength(prefSpeed()).scl(-1f);
unit.movePref(vec);
if(!unit.within(u, unit.type.circleTargetRadius*0.5f + u.physicSize())){
turningAway = false;
}
return;
}else if(unit.within(u, avoidDist)){
turningAway = true;
}
}
if(diff > 70f && vec.len() < circleLength){
vec.setAngle(unit.vel().angle());
}else{
}else if(unit.type.omniMovement){ //non-omni movement units don't need to do this as the turning is already smoothed out
vec.setAngle(Angles.moveToward(unit.vel().angle(), vec.angle(), 6f));
}

View File

@@ -22,7 +22,7 @@ import java.util.*;
/** The current implementation is awful. Consider it a proof of concept. */
@SuppressWarnings("unchecked")
public class ContentPatcher{
public class DataPatcher{
private static final Object root = new Object();
private static final ObjectMap<String, ContentType> nameToType = new ObjectMap<>();
private static ContentParser parser = createParser();
@@ -129,6 +129,8 @@ public class ContentPatcher{
if(!Vars.headless){
if(object instanceof DrawPart part && parent instanceof MappableContent cont){
part.load(cont.name);
}else if(object instanceof DrawPart part && parent instanceof Weapon w){
part.load(w.name);
}else if(object instanceof DrawBlock draw && parent instanceof Block block){
draw.load(block);
}else if(object instanceof Weapon weapon){

View File

@@ -93,6 +93,8 @@ public class UnitType extends UnlockableContent implements Senseable{
mineRange = 70f,
/** range at which this unit can build */
buildRange = Vars.buildingRange,
/** radius for circleTarget, if true */
circleTargetRadius = 80f,
/** multiplier for damage this (flying) unit deals when crashing on enemy things */
crashDamageMultiplier = 1f,
/** multiplier for health that this flying unit has for its wreck, based on its max health. */