Flare AI changed
This commit is contained in:
@@ -472,7 +472,7 @@ editor.generation = Generation
|
|||||||
editor.objectives = Objectives
|
editor.objectives = Objectives
|
||||||
editor.locales = Locale Bundles
|
editor.locales = Locale Bundles
|
||||||
editor.patches.guide = Patch Guide
|
editor.patches.guide = Patch Guide
|
||||||
editor.patches = Content Patches
|
editor.patches = Data Patches
|
||||||
editor.patch: Patchset: {0}
|
editor.patch: Patchset: {0}
|
||||||
editor.patches.none = [lightgray]No patchsets loaded.
|
editor.patches.none = [lightgray]No patchsets loaded.
|
||||||
editor.patches.errors = Patchset Errors
|
editor.patches.errors = Patchset Errors
|
||||||
|
|||||||
@@ -270,7 +270,6 @@ public class CommandAI extends AIController{
|
|||||||
|
|
||||||
Building targetBuild = world.buildWorld(targetPos.x, targetPos.y);
|
Building targetBuild = world.buildWorld(targetPos.x, targetPos.y);
|
||||||
|
|
||||||
|
|
||||||
//TODO: should the unit stop when it finds a target?
|
//TODO: should the unit stop when it finds a target?
|
||||||
if(
|
if(
|
||||||
(hasStance(UnitStance.patrol) && !hasStance(UnitStance.pursueTarget) && target != null && unit.within(target, unit.type.range - 2f) && !unit.type.circleTarget) ||
|
(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(move){
|
||||||
if(unit.type.circleTarget && attackTarget != null){
|
if(unit.type.circleTarget && attackTarget != null){
|
||||||
target = attackTarget;
|
target = attackTarget;
|
||||||
circleAttack(80f);
|
circleAttack(unit.type.circleTargetRadius);
|
||||||
}else{
|
}else{
|
||||||
moveTo(vecOut,
|
moveTo(vecOut,
|
||||||
withinAttackRange ? engageRange :
|
withinAttackRange ? engageRange :
|
||||||
@@ -362,7 +361,7 @@ public class CommandAI extends AIController{
|
|||||||
attackTarget = null;
|
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);
|
unit.lookAt(vecMovePos);
|
||||||
}else{
|
}else{
|
||||||
faceTarget();
|
faceTarget();
|
||||||
@@ -379,7 +378,11 @@ public class CommandAI extends AIController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
}else if(target != null){
|
}else if(target != null){
|
||||||
faceTarget();
|
if(unit.type.circleTarget && shouldFire()){
|
||||||
|
circleAttack(unit.type.circleTargetRadius);
|
||||||
|
}else{
|
||||||
|
faceTarget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class FlyingAI extends AIController{
|
|||||||
|
|
||||||
if(target != null && unit.hasWeapons()){
|
if(target != null && unit.hasWeapons()){
|
||||||
if(unit.type.circleTarget){
|
if(unit.type.circleTarget){
|
||||||
circleAttack(120f);
|
circleAttack(unit.type.circleTargetRadius);
|
||||||
}else{
|
}else{
|
||||||
moveTo(target, unit.type.range * 0.8f);
|
moveTo(target, unit.type.range * 0.8f);
|
||||||
unit.lookAt(target);
|
unit.lookAt(target);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class RepairAI extends AIController{
|
|||||||
|
|
||||||
if(target != null && target instanceof Building b && b.team == unit.team){
|
if(target != null && target instanceof Building b && b.team == unit.team){
|
||||||
if(unit.type.circleTarget){
|
if(unit.type.circleTarget){
|
||||||
circleAttack(120f);
|
circleAttack(unit.type.circleTargetRadius);
|
||||||
}else if(!target.within(unit, unit.type.range * 0.65f)){
|
}else if(!target.within(unit, unit.type.range * 0.65f)){
|
||||||
moveTo(target, unit.type.range * 0.65f);
|
moveTo(target, unit.type.range * 0.65f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -995,18 +995,25 @@ public class UnitTypes{
|
|||||||
flying = true;
|
flying = true;
|
||||||
health = 70;
|
health = 70;
|
||||||
engineOffset = 5.75f;
|
engineOffset = 5.75f;
|
||||||
//TODO balance
|
|
||||||
//targetAir = false;
|
|
||||||
targetFlags = new BlockFlag[]{BlockFlag.generator, null};
|
targetFlags = new BlockFlag[]{BlockFlag.generator, null};
|
||||||
hitSize = 9;
|
hitSize = 9;
|
||||||
itemCapacity = 10;
|
itemCapacity = 10;
|
||||||
|
circleTarget = true;
|
||||||
|
omniMovement = false;
|
||||||
|
rotateSpeed = 5f;
|
||||||
|
circleTargetRadius = 60f;
|
||||||
|
|
||||||
weapons.add(new Weapon(){{
|
weapons.add(new Weapon(){{
|
||||||
y = 0f;
|
y = 1f;
|
||||||
x = 2f;
|
x = 0f;
|
||||||
reload = 20f;
|
minShootVelocity = 2f;
|
||||||
|
shootCone = 10f;
|
||||||
|
reload = 80f;
|
||||||
|
shoot.shots = 3;
|
||||||
|
shoot.shotDelay = 3f;
|
||||||
ejectEffect = Fx.casing1;
|
ejectEffect = Fx.casing1;
|
||||||
bullet = new BasicBulletType(2.5f, 9){{
|
mirror = false;
|
||||||
|
bullet = new BasicBulletType(2.5f, 15){{
|
||||||
width = 7f;
|
width = 7f;
|
||||||
height = 9f;
|
height = 9f;
|
||||||
lifetime = 45f;
|
lifetime = 45f;
|
||||||
@@ -1014,7 +1021,7 @@ public class UnitTypes{
|
|||||||
smokeEffect = Fx.shootSmallSmoke;
|
smokeEffect = Fx.shootSmallSmoke;
|
||||||
ammoMultiplier = 2;
|
ammoMultiplier = 2;
|
||||||
}};
|
}};
|
||||||
shootSound = Sounds.pew;
|
shootSound = Sounds.shootDagger;
|
||||||
}});
|
}});
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -1035,9 +1042,12 @@ public class UnitTypes{
|
|||||||
targetFlags = new BlockFlag[]{BlockFlag.factory, null};
|
targetFlags = new BlockFlag[]{BlockFlag.factory, null};
|
||||||
circleTarget = true;
|
circleTarget = true;
|
||||||
ammoType = new ItemAmmoType(Items.graphite);
|
ammoType = new ItemAmmoType(Items.graphite);
|
||||||
|
omniMovement = false;
|
||||||
|
rotateSpeed = 4.5f;
|
||||||
|
circleTargetRadius = 40f;
|
||||||
|
|
||||||
weapons.add(new Weapon(){{
|
weapons.add(new Weapon(){{
|
||||||
minShootVelocity = 0.75f;
|
minShootVelocity = 1f;
|
||||||
x = 3f;
|
x = 3f;
|
||||||
shootY = 0f;
|
shootY = 0f;
|
||||||
reload = 12f;
|
reload = 12f;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class GameState{
|
|||||||
/** Team data. Gets reset every new game. */
|
/** Team data. Gets reset every new game. */
|
||||||
public Teams teams = new Teams();
|
public Teams teams = new Teams();
|
||||||
/** Handles JSON edits of game content. */
|
/** 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. */
|
/** Number of enemies in the game; only used clientside in servers. */
|
||||||
public int enemies;
|
public int enemies;
|
||||||
/** Map being playtested (not edited!) */
|
/** Map being playtested (not edited!) */
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class RegionPart extends DrawPart{
|
|||||||
int i = params.sideOverride == -1 ? s : params.sideOverride;
|
int i = params.sideOverride == -1 ? s : params.sideOverride;
|
||||||
|
|
||||||
//can be null
|
//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;
|
float sign = (i == 0 ? 1 : -1) * params.sideMultiplier;
|
||||||
Tmp.v1.set((x + mx) * sign, y + my).rotateRadExact((params.rotation - 90) * Mathf.degRad);
|
Tmp.v1.set((x + mx) * sign, y + my).rotateRadExact((params.rotation - 90) * Mathf.degRad);
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public class AIController implements UnitController{
|
|||||||
/** main target that is being faced */
|
/** main target that is being faced */
|
||||||
protected @Nullable Teamc target;
|
protected @Nullable Teamc target;
|
||||||
protected @Nullable Teamc bomberTarget;
|
protected @Nullable Teamc bomberTarget;
|
||||||
|
protected boolean turningAway;
|
||||||
|
|
||||||
{
|
{
|
||||||
resetTimers();
|
resetTimers();
|
||||||
@@ -155,7 +156,8 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void targetInvalidated(){
|
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(){
|
public void updateWeapons(){
|
||||||
@@ -169,7 +171,7 @@ public class AIController implements UnitController{
|
|||||||
noTargetTime += Time.delta;
|
noTargetTime += Time.delta;
|
||||||
|
|
||||||
if(invalid(target)){
|
if(invalid(target)){
|
||||||
if(target != null && !target.isAdded()){
|
if(target instanceof Healthc h && !h.isValid()){
|
||||||
targetInvalidated();
|
targetInvalidated();
|
||||||
}
|
}
|
||||||
target = null;
|
target = null;
|
||||||
@@ -300,14 +302,32 @@ public class AIController implements UnitController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void circleAttack(float circleLength){
|
public void circleAttack(float circleLength){
|
||||||
|
if(target == null) return;
|
||||||
|
|
||||||
vec.set(target).sub(unit);
|
vec.set(target).sub(unit);
|
||||||
|
|
||||||
float ang = unit.angleTo(target);
|
float ang = unit.angleTo(target);
|
||||||
float diff = Angles.angleDist(ang, unit.rotation());
|
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){
|
if(diff > 70f && vec.len() < circleLength){
|
||||||
vec.setAngle(unit.vel().angle());
|
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));
|
vec.setAngle(Angles.moveToward(unit.vel().angle(), vec.angle(), 6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import java.util.*;
|
|||||||
|
|
||||||
/** The current implementation is awful. Consider it a proof of concept. */
|
/** The current implementation is awful. Consider it a proof of concept. */
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class ContentPatcher{
|
public class DataPatcher{
|
||||||
private static final Object root = new Object();
|
private static final Object root = new Object();
|
||||||
private static final ObjectMap<String, ContentType> nameToType = new ObjectMap<>();
|
private static final ObjectMap<String, ContentType> nameToType = new ObjectMap<>();
|
||||||
private static ContentParser parser = createParser();
|
private static ContentParser parser = createParser();
|
||||||
@@ -129,6 +129,8 @@ public class ContentPatcher{
|
|||||||
if(!Vars.headless){
|
if(!Vars.headless){
|
||||||
if(object instanceof DrawPart part && parent instanceof MappableContent cont){
|
if(object instanceof DrawPart part && parent instanceof MappableContent cont){
|
||||||
part.load(cont.name);
|
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){
|
}else if(object instanceof DrawBlock draw && parent instanceof Block block){
|
||||||
draw.load(block);
|
draw.load(block);
|
||||||
}else if(object instanceof Weapon weapon){
|
}else if(object instanceof Weapon weapon){
|
||||||
@@ -93,6 +93,8 @@ public class UnitType extends UnlockableContent implements Senseable{
|
|||||||
mineRange = 70f,
|
mineRange = 70f,
|
||||||
/** range at which this unit can build */
|
/** range at which this unit can build */
|
||||||
buildRange = Vars.buildingRange,
|
buildRange = Vars.buildingRange,
|
||||||
|
/** radius for circleTarget, if true */
|
||||||
|
circleTargetRadius = 80f,
|
||||||
/** multiplier for damage this (flying) unit deals when crashing on enemy things */
|
/** multiplier for damage this (flying) unit deals when crashing on enemy things */
|
||||||
crashDamageMultiplier = 1f,
|
crashDamageMultiplier = 1f,
|
||||||
/** multiplier for health that this flying unit has for its wreck, based on its max health. */
|
/** multiplier for health that this flying unit has for its wreck, based on its max health. */
|
||||||
|
|||||||
Reference in New Issue
Block a user