From fdfc43ce7264314fdfb06f6a62abb7a81c0229e3 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 29 Jan 2022 13:44:38 -0500 Subject: [PATCH] Correct quell AI --- .../mindustry/ai/types/FlyingFollowAI.java | 62 +++++++++++++++++++ core/src/mindustry/content/UnitTypes.java | 3 + .../entities/units/AIController.java | 7 ++- .../maps/planet/ErekirPlanetGenerator.java | 3 +- core/src/mindustry/type/UnitType.java | 6 +- core/src/mindustry/type/Weapon.java | 4 ++ 6 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 core/src/mindustry/ai/types/FlyingFollowAI.java diff --git a/core/src/mindustry/ai/types/FlyingFollowAI.java b/core/src/mindustry/ai/types/FlyingFollowAI.java new file mode 100644 index 0000000000..7956ca19cc --- /dev/null +++ b/core/src/mindustry/ai/types/FlyingFollowAI.java @@ -0,0 +1,62 @@ +package mindustry.ai.types; + +import arc.math.*; +import arc.util.*; +import mindustry.*; +import mindustry.entities.*; +import mindustry.entities.units.*; +import mindustry.gen.*; + +/** AI/wave team only! This is used for wave support flyers. */ +public class FlyingFollowAI extends FlyingAI{ + public Teamc following; + + @Override + public void updateMovement(){ + unloadPayloads(); + + if(following != null){ + moveTo(following, (following instanceof Sized s ? s.hitSize()/2f * 1.1f : 0f) + unit.hitSize/2f + 15f, 50f); + }else if(target != null && unit.hasWeapons()){ + moveTo(target, 80f); + } + + if(shouldFaceTarget()){ + unit.lookAt(target); + Log.info("lookAt target = @", target); + }else if(following != null){ + unit.lookAt(following); + } + + if(timer.get(timerTarget3, 30f)){ + following = Units.closest(unit.team, unit.x, unit.y, Math.max(unit.type.range, 400f), u -> !u.dead() && u.type != unit.type, (u, tx, ty) -> -u.maxHealth + Mathf.dst2(u.x, u.y, tx, ty) / 6400f); + } + } + + public boolean shouldFaceTarget(){ + return target != null && (following == null || unit.within(target, unit.range())); + } + + @Override + public void updateVisuals(){ + if(unit.isFlying()){ + unit.wobble(); + + if(!shouldFaceTarget()){ + unit.lookAt(unit.prefRotation()); + } + } + } + + @Override + public AIController fallback(){ + return new FlyingAI(); + } + + @Override + public boolean useFallback(){ + //only AI teams use this controller + return Vars.state.rules.pvp || Vars.state.rules.waveTeam != unit.team; + } + +} diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index 2e2a450af5..f21de9f30e 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -2603,6 +2603,7 @@ public class UnitTypes{ //region erekir - flying quell = new UnitType("quell"){{ + defaultController = FlyingFollowAI::new; envDisabled = 0; outlineColor = Pal.darkOutline; @@ -2639,6 +2640,8 @@ public class UnitTypes{ shootEffect = Fx.shootBig; smokeEffect = Fx.shootBigSmoke2; shake = 1f; + speed = 0f; + keepVelocity = false; }}; unitSpawned = new MissileUnitType("quell-missile"){{ diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 64cff57fb1..fe6d072579 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -125,6 +125,7 @@ public class AIController implements UnitController{ for(var mount : unit.mounts){ Weapon weapon = mount.weapon; + float wrange = weapon.range(); //let uncontrollable weapons do their own thing if(!weapon.controllable) continue; @@ -136,10 +137,10 @@ public class AIController implements UnitController{ mount.target = target; }else{ if(ret){ - mount.target = findTarget(mountX, mountY, weapon.bullet.range(), weapon.bullet.collidesAir, weapon.bullet.collidesGround); + mount.target = findTarget(mountX, mountY, wrange, weapon.bullet.collidesAir, weapon.bullet.collidesGround); } - if(checkTarget(mount.target, mountX, mountY, weapon.bullet.range())){ + if(checkTarget(mount.target, mountX, mountY, wrange)){ mount.target = null; } } @@ -147,7 +148,7 @@ public class AIController implements UnitController{ boolean shoot = false; if(mount.target != null){ - shoot = mount.target.within(mountX, mountY, weapon.bullet.range() + (mount.target instanceof Sized s ? s.hitSize()/2f : 0f)) && shouldShoot(); + shoot = mount.target.within(mountX, mountY, wrange + (mount.target instanceof Sized s ? s.hitSize()/2f : 0f)) && shouldShoot(); Vec2 to = Predict.intercept(unit, mount.target, weapon.bullet.speed); mount.aimX = to.x; diff --git a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java index f64572d848..d6a9c17b0b 100644 --- a/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java +++ b/core/src/mindustry/maps/planet/ErekirPlanetGenerator.java @@ -17,7 +17,6 @@ import mindustry.world.meta.*; import static mindustry.Vars.*; public class ErekirPlanetGenerator extends PlanetGenerator{ - //public float scl = 2f; public float heightScl = 0.9f, octaves = 8, persistence = 0.7f, heightPow = 3f, heightMult = 1.6f; //TODO inline/remove @@ -407,6 +406,8 @@ public class ErekirPlanetGenerator extends PlanetGenerator{ //it is very hot state.rules.attributes.set(Attribute.heat, 0.8f); state.rules.environment = sector.planet.defaultEnv; + + //TODO remove slag and arkycite around core. Schematics.placeLaunchLoadout(spawnX, spawnY); //all sectors are wave sectors diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 60d18afa23..e3ca36dd56 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -417,8 +417,8 @@ public class UnitType extends UnlockableContent{ if(range < 0){ range = Float.MAX_VALUE; for(Weapon weapon : weapons){ - range = Math.min(range, weapon.bullet.range() - margin); - maxRange = Math.max(maxRange, weapon.bullet.range() - margin); + range = Math.min(range, weapon.range() - margin); + maxRange = Math.max(maxRange, weapon.range() - margin); } } @@ -426,7 +426,7 @@ public class UnitType extends UnlockableContent{ maxRange = Math.max(0f, range); for(Weapon weapon : weapons){ - maxRange = Math.max(maxRange, weapon.bullet.range() - margin); + maxRange = Math.max(maxRange, weapon.range() - margin); } } diff --git a/core/src/mindustry/type/Weapon.java b/core/src/mindustry/type/Weapon.java index 83c3a002e6..aa3d63e446 100644 --- a/core/src/mindustry/type/Weapon.java +++ b/core/src/mindustry/type/Weapon.java @@ -216,6 +216,10 @@ public class Weapon implements Cloneable{ Draw.z(z); } + public float range(){ + return unitSpawned != null ? unitSpawned.lifetime * unitSpawned.speed : bullet.range(); + } + public void update(Unit unit, WeaponMount mount){ boolean can = unit.canShoot(); float lastReload = mount.reload;