1package com.fs.starfarer.api.impl.combat;
3import java.util.ArrayList;
4import java.util.Iterator;
7import org.lwjgl.util.vector.Vector2f;
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.combat.CollisionGridAPI;
11import com.fs.starfarer.api.combat.CombatEngineAPI;
12import com.fs.starfarer.api.combat.CombatEntityAPI;
13import com.fs.starfarer.api.combat.MissileAIPlugin;
14import com.fs.starfarer.api.combat.MissileAPI;
15import com.fs.starfarer.api.combat.ShipAPI;
16import com.fs.starfarer.api.combat.ShipCommand;
17import com.fs.starfarer.api.impl.combat.MoteControlScript.SharedMoteAIData;
18import com.fs.starfarer.api.util.FaderUtil;
19import com.fs.starfarer.api.util.IntervalUtil;
20import com.fs.starfarer.api.util.Misc;
36 protected List<MissileAPI>
missileList =
new ArrayList<MissileAPI>();
37 protected List<CombatEntityAPI>
hardAvoidList =
new ArrayList<CombatEntityAPI>();
42 protected SharedMoteAIData
data;
46 r = (float) Math.random();
47 elapsed = -(float) Math.random() * 0.5f;
59 while (iter.hasNext()) {
60 Object o = iter.next();
61 if (!(o instanceof
ShipAPI))
continue;
71 while (iter.hasNext()) {
72 Object o = iter.next();
94 float sin = (float) Math.sin(
data.elapsed * 1f);
95 float mult = 1f + sin * 0.25f;
98 Vector2f total =
new Vector2f();
101 if (attractor !=
null) {
104 float f = dist / 200f;
107 Vector2f.add(total, dir, total);
112 boolean hardAvoiding =
false;
115 float hardAvoidRange = other.getCollisionRadius() + avoidRange + 50f;
116 if (dist < hardAvoidRange) {
118 float f = 1f - dist / (hardAvoidRange);
120 Vector2f.add(total, dir, total);
121 hardAvoiding = f > 0.5f;
128 if (otherMissile ==
missile)
continue;
136 float currCohesionRange = cohesionRange;
138 if (dist < avoidRange && otherMissile !=
missile && !hardAvoiding) {
140 float f = 1f - dist / avoidRange;
142 Vector2f.add(total, dir, total);
145 if (dist < currCohesionRange) {
146 Vector2f dir =
new Vector2f(otherMissile.
getVelocity());
148 float f = 1f - dist / currCohesionRange;
150 Vector2f.add(total, dir, total);
164 if (dist > sourceRejoin) {
166 float f = dist / (sourceRejoin + 400f) - 1f;
169 Vector2f.add(total, dir, total);
172 if (dist < sourceRepel) {
174 float f = 1f - dist / sourceRepel;
176 Vector2f.add(total, dir, total);
179 if (dist < sourceCohesion && source.
getVelocity().length() > 20f) {
182 float f = 1f - dist / sourceCohesion;
184 Vector2f.add(total, dir, total);
188 if (total.length() <= 0.05f) {
189 float offset =
r > 0.5f ? 90f : -90f;
194 Vector2f.add(total, dir, total);
198 if (total.length() > 0) {
235 ((
float) Math.random() > 0.9f ||
236 (
data.attractorLock !=
null && (
float) Math.random() > 0.5f))) {
273 if (
data.attractorLock !=
null) {
299 if (
tracker.intervalElapsed()) {
308 @SuppressWarnings(
"unchecked")
327 if (
data.attractorLock !=
null) {
337 int maxMotesPerMissile = 2;
341 float minDist = Float.MAX_VALUE;
344 if (other.getOwner() == owner)
continue;
345 if (other.getOwner() == 100)
continue;
348 if (distToTarget > minDist)
continue;
349 if (distToTarget > 3000 && !engine.
isAwareOf(owner, other))
continue;
351 float distFromAttractor = Float.MAX_VALUE;
352 if (
data.attractorTarget !=
null) {
356 if (distFromSource > maxDistFromSourceShip &&
357 distFromAttractor > maxDistFromAttractor)
continue;
360 if (distToTarget < minDist) {
362 minDist = distToTarget;
367 if (other.getOwner() == owner)
continue;
368 if (other.getOwner() == 100)
continue;
369 if (!other.isFighter())
continue;
371 if (distToTarget > minDist)
continue;
372 if (distToTarget > 3000 && !engine.
isAwareOf(owner, other))
continue;
374 float distFromAttractor = Float.MAX_VALUE;
375 if (
data.attractorTarget !=
null) {
379 if (distFromSource > maxDistFromSourceShip &&
380 distFromAttractor > maxDistFromAttractor)
continue;
383 if (distToTarget < minDist) {
385 minDist = distToTarget;
407 Vector2f attractor =
null;
408 if (
data.attractorTarget !=
null) {
409 attractor =
data.attractorTarget;
410 if (
data.attractorLock !=
null) {
static CombatEngineAPI getCombatEngine()
static float MAX_FLOCK_RANGE
static float MAX_HARD_AVOID_RANGE
List< CombatEntityAPI > hardAvoidList
MoteAIScript(MissileAPI missile)
static float COHESION_RANGE
void acquireNewTargetIfNeeded()
Vector2f getAttractorLoc()
List< MissileAPI > missileList
static float ATTRACTOR_LOCK_STOP_FLOCKING_ADD
void advance(float amount)
IntervalUtil flutterCheck
CombatEntityAPI getTarget()
void updateHardAvoidList()
void setTarget(CombatEntityAPI target)
int getNumMotesTargeting(CombatEntityAPI other)
IntervalUtil updateListTracker
static float MAX_DIST_FROM_SOURCE_TO_ENGAGE_AS_PD
static float MAX_DIST_FROM_ATTRACTOR_TO_ENGAGE_AS_PD
static SharedMoteAIData getSharedData(ShipAPI source)
void advance(float amount)
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static float getAngleInDegrees(Vector2f v)
static Vector2f normalise(Vector2f v)
Iterator< Object > getCheckIterator(Vector2f loc, float checkWidth, float checkHeight)
boolean isAwareOf(int owner, CombatEntityAPI other)
Vector2f getAimPointWithLeadForAutofire(CombatEntityAPI from, float accuracyFactor, CombatEntityAPI to, float projSpeed)
CollisionGridAPI getAiGridAsteroids()
void headInDirectionWithoutTurning(MissileAPI missile, float desiredHeading, float desiredSpeed)
List< MissileAPI > getMissiles()
CollisionGridAPI getAiGridShips()
List< ShipAPI > getShips()
float getCollisionRadius()
void giveCommand(ShipCommand command)
MissileAIPlugin getUnwrappedMissileAI()
ShipEngineControllerAPI getEngineController()
void forceShowAccelerating()