1package com.fs.starfarer.api.impl.combat.dweller;
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.CollisionClass;
11import com.fs.starfarer.api.combat.CombatEngineAPI;
12import com.fs.starfarer.api.combat.DamageType;
13import com.fs.starfarer.api.combat.ShipAIConfig;
14import com.fs.starfarer.api.combat.ShipAIPlugin;
15import com.fs.starfarer.api.combat.ShipAPI;
16import com.fs.starfarer.api.combat.ShipCommand;
17import com.fs.starfarer.api.combat.ShipwideAIFlags;
18import com.fs.starfarer.api.combat.WeaponGroupAPI;
19import com.fs.starfarer.api.util.IntervalUtil;
20import com.fs.starfarer.api.util.Misc;
21import com.fs.starfarer.api.util.WeightedRandomPicker;
25 public static class FlockingData {
32 public float repelAtAngleDist;
35 public float attractWeight;
36 public float repelWeight;
37 public float cohesionWeight;
83 if (groups.size() <= groupNum)
return;
84 groups.get(groupNum).toggleOn();
88 if (groups.size() <= groupNum)
return;
89 groups.get(groupNum).toggleOff();
140 if (shroud !=
null) {
142 if (sourceShip !=
null) {
199 range * 2f, range * 2f);
209 while (iter.hasNext()) {
210 Object o = iter.next();
211 if (!(o instanceof
ShipAPI))
continue;
214 if (other ==
ship)
continue;
215 if (other.
getOwner() == owner)
continue;
216 if (other.
isHulk())
continue;
224 if (dist > range)
continue;
239 float f = angleDiff / 90f;
242 float minus = 5f * dist / 5000f;
243 if (minus > 5f) minus = 3f;
249 if (dist > goodRange) {
250 lessGood.
add(other, score);
252 good.
add(other, score);
273 return lessGood.
pick();
290 FlockingData data =
new FlockingData();
294 data.attractWeight = 100f;
296 data.attractWeight *= 10f;
298 data.repelWeight = 0f;
300 data.maxA = 1000000f;
303 data.repelAtAngleDist = 0f;
308 if (curr ==
ship)
continue;
309 if (curr.getOwner() != owner)
continue;
310 if (curr.isHulk() || curr.getOwner() == 100)
continue;
312 float currRadius = curr.getCollisionRadius();
315 FlockingData data =
new FlockingData();
317 data.loc = curr.getLocation();
318 data.vel = curr.getVelocity();
319 data.repelWeight = 100f;
320 data.cohesionWeight = 1f;
321 data.attractWeight = 3f;
323 data.minA = 0f + radius + currRadius;
333 }
else if (!curr.isFighter()) {
334 FlockingData data =
new FlockingData();
336 data.loc = curr.getLocation();
337 data.vel = curr.getVelocity();
338 data.attractWeight = 0f;
339 data.cohesionWeight = 0f;
340 data.repelWeight = 100f;
362 Vector2f total =
new Vector2f();
366 if (curr.maxR > 0 && dist < curr.maxR) {
367 float repelWeight = curr.repelWeight;
368 if (dist > curr.minR && curr.maxR > curr.minR) {
369 repelWeight = (dist - curr.minR) / (curr.maxR - curr.minR);
370 if (repelWeight > 1f) repelWeight = 1f;
371 repelWeight = 1f - repelWeight;
372 repelWeight *= curr.repelWeight;
377 float distIntoRepel = curr.maxR - dist;
378 float repelAdjustmentAngle = 0f;
379 if (distIntoRepel < curr.repelAtAngleDist && curr.repelAtAngleDist > 0) {
380 float repelMult = (1f - distIntoRepel / curr.repelAtAngleDist);
381 repelAdjustmentAngle = 90f * repelMult;
382 repelWeight *= (1f - repelMult);
386 repelAdjustmentAngle *= turnDir;
390 dir.scale(repelWeight);
391 Vector2f.add(total, dir, total);
394 if (curr.maxA > 0 && dist < curr.maxA) {
395 float attractWeight = curr.attractWeight;
396 if (dist > curr.minA && curr.maxA > curr.minA) {
397 attractWeight = (dist - curr.minA) / (curr.maxA - curr.minA);
398 if (attractWeight > 1f) attractWeight = 1f;
399 attractWeight = 1f - attractWeight;
400 attractWeight *= curr.attractWeight;
404 dir.scale(attractWeight);
405 Vector2f.add(total, dir, total);
408 if (curr.maxC > 0 && dist < curr.maxC) {
409 float cohesionWeight = curr.cohesionWeight;
410 if (dist > curr.minC && curr.maxC > curr.minC) {
411 cohesionWeight = (dist - curr.minC) / (curr.maxC - curr.minC);
412 if (cohesionWeight > 1f) cohesionWeight = 1f;
413 cohesionWeight = 1f - cohesionWeight;
414 cohesionWeight *= curr.cohesionWeight;
417 Vector2f dir =
new Vector2f(curr.vel);
419 dir.scale(cohesionWeight);
420 Vector2f.add(total, dir, total);
424 if (total.length() <= 0) {
static CombatEngineAPI getCombatEngine()
static DwellerShroud getShroudFor(CombatEntityAPI entity)
static float HULL_FRACTION_LOST_PER_SECOND
static float ATTRACTOR_RANGE_MAX
void toggleOff(int groupNum)
void toggleOn(int groupNum)
List< FlockingData > flockingData
void updateFlockingData()
void cancelCurrentManeuver()
void advance(float amount)
ShroudedVortexAI(ShipAPI ship)
static float COHESION_RANGE_MAX
static float REPEL_RANGE_MAX
static float REPEL_RANGE_MIN
void giveMovementCommands()
void setDoNotFireDelay(float amount)
IntervalUtil headingInterval
static String VORTEX_FLOCKING
void forceCircumstanceEvaluation()
void computeDesiredHeading()
static float COHESION_RANGE_MIN
IntervalUtil updateInterval
ShipwideAIFlags getAIFlags()
static String TAG_MIRRORED_VORTEX
void forceIntervalElapsed()
void advance(float amount)
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
static float getAngleDiff(float from, float to)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static Vector2f getUnitVector(Vector2f from, Vector2f to)
static float getClosestTurnDirection(float facing, float desired)
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)
CollisionGridAPI getShipGrid()
void applyDamage(CombatEntityAPI entity, Vector2f point, float damageAmount, DamageType damageType, float empAmount, boolean bypassShields, boolean dealsSoftFlux, Object source, boolean playSound)
Vector2f getAimPointWithLeadForAutofire(CombatEntityAPI from, float accuracyFactor, CombatEntityAPI to, float projSpeed)
void headInDirectionWithoutTurning(MissileAPI missile, float desiredHeading, float desiredSpeed)
List< ShipAPI > getShips()
void setCollisionClass(CollisionClass collisionClass)
float getCollisionRadius()
CollisionClass getCollisionClass()
float getMaxSpeedWithoutBoost()
void setHitpoints(float value)
boolean hasTag(String tag)
List< WeaponGroupAPI > getWeaponGroupsCopy()
void giveCommand(ShipCommand command, Object param, int groupNumber)