1package com.fs.starfarer.api.impl.combat;
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.Iterator;
11import org.lwjgl.util.vector.Vector2f;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
15import com.fs.starfarer.api.combat.CollisionClass;
16import com.fs.starfarer.api.combat.CombatEngineAPI;
17import com.fs.starfarer.api.combat.CombatEngineLayers;
18import com.fs.starfarer.api.combat.CombatEntityAPI;
19import com.fs.starfarer.api.combat.DamageType;
20import com.fs.starfarer.api.combat.EmpArcEntityAPI;
21import com.fs.starfarer.api.combat.EmpArcEntityAPI.EmpArcParams;
22import com.fs.starfarer.api.combat.EveryFrameCombatPlugin;
23import com.fs.starfarer.api.combat.MissileAPI;
24import com.fs.starfarer.api.combat.MutableShipStatsAPI;
25import com.fs.starfarer.api.combat.ShipAPI;
26import com.fs.starfarer.api.combat.ShipSystemAPI;
27import com.fs.starfarer.api.combat.ShipSystemAPI.SystemState;
28import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
29import com.fs.starfarer.api.impl.campaign.ids.HullMods;
30import com.fs.starfarer.api.input.InputEventAPI;
31import com.fs.starfarer.api.loading.WeaponSlotAPI;
32import com.fs.starfarer.api.util.IntervalUtil;
33import com.fs.starfarer.api.util.Misc;
34import com.fs.starfarer.api.util.WeightedRandomPicker;
71 public static class MoteData {
72 public Color jitterColor;
73 public Color empColor;
77 public float antiFighterDamage;
78 public String impactSound;
79 public String loopSound;
82 public static Map<String, MoteData>
MOTE_DATA =
new HashMap<String, MoteData>();
88 MoteData normal =
new MoteData();
89 normal.jitterColor =
new Color(100,165,255,175);
90 normal.empColor =
new Color(100,165,255,255);
93 normal.impactSound =
"mote_attractor_impact_normal";
94 normal.loopSound =
"mote_attractor_loop";
98 MoteData hf =
new MoteData();
99 hf.jitterColor =
new Color(255,100,255,175);
100 hf.empColor =
new Color(255,100,255,255);
103 hf.impactSound =
"mote_attractor_impact_damage";
104 hf.loopSound =
"mote_attractor_loop_dark";
141 public static class SharedMoteAIData {
142 public float elapsed = 0f;
143 public List<MissileAPI> motes =
new ArrayList<MissileAPI>();
145 public float attractorRemaining = 0f;
146 public Vector2f attractorTarget =
null;
147 public ShipAPI attractorLock =
null;
151 String key = source +
"_mote_AI_shared";
154 data =
new SharedMoteAIData();
173 if (slot.isSystemSlot()) {
174 if (slot.getSlotSize() == WeaponSize.SMALL) {
177 if (slot.getSlotSize() == WeaponSize.MEDIUM) {
197 data.elapsed += amount;
199 if (data.attractorRemaining > 0) {
200 data.attractorRemaining -= amount;
201 if (data.attractorRemaining <= 0 ||
202 (data.attractorLock !=
null && !data.attractorLock.
isAlive()) ||
203 data.motes.isEmpty()) {
204 data.attractorTarget =
null;
205 data.attractorLock =
null;
206 data.attractorRemaining = 0;
209 if (effectLevel <= 0) {
222 Iterator<MissileAPI> iter = data.motes.iterator();
223 while (iter.hasNext()) {
238 if (data.motes.size() < maxMotes && data.attractorLock ==
null &&
246 float arc = slot.
getArc();
247 dir += arc * (float) Math.random() - arc /2f;
260 data.motes.add(mote);
269 float fraction = data.motes.size() / (Math.max(1f, maxMotes));
270 float volume = fraction * 3f;
271 if (volume > 1f) volume = 1f;
272 if (data.motes.size() > 3) {
273 Vector2f com =
new Vector2f();
277 com.scale(1f / data.motes.size());
288 if (effectLevel == 1) {
290 if (data.attractorTarget ==
null) {
300 if (data.attractorLock !=
null) {
301 target = data.attractorLock;
304 EmpArcParams params =
new EmpArcParams();
310 params.segmentLengthMult = 8f;
311 params.zigZagReductionFactor = 0.15f;
313 params.brightSpotFullFraction = 0.5f;
314 params.brightSpotFadeFraction = 0.5f;
318 params.flickerRateMult = 0.6f - dist / 3000f;
319 if (params.flickerRateMult < 0.3f) {
320 params.flickerRateMult = 0.3f;
338 "mote_attractor_targeted_ship",
342 new Color(255,255,255,255),
345 if (data.attractorLock !=
null) {
354 if (data.attractorLock ==
null) {
398 if (data.attractorTarget ==
null)
return;
402 Vector2f targetLoc = data.attractorTarget;
405 float maxRadius = 300f;
406 float minRadius = 200f;
408 if (data.attractorLock !=
null) {
415 float maxDur = 0.75f;
419 for (
int i = 0; i < glows; i++) {
420 float radius = minRadius + (float) Math.random() * (maxRadius - minRadius);
425 float dur = minDur + (float) Math.random() * (maxDur - minDur);
426 float speed = dist / dur;
429 float size = minSize + (float) Math.random() * (maxSize - minSize);
432 engine.
addHitParticle(loc, dir, size * 0.5f, 1f, 0.3f, dur, Color.white);
440 public StatusData
getStatusData(
int index, State state,
float effectLevel) {
451 if (data.attractorLock !=
null) {
452 targetLoc =
new Vector2f(data.attractorLock.
getLocation());
455 data.attractorTarget = targetLoc;
457 if (data.attractorLock !=
null) {
469 if (system.
getState() != SystemState.IDLE)
return null;
476 return "OUT OF RANGE";
508 Vector2f.add(targetLoc, slotLoc, targetLoc);
533 if (other.isFighter())
continue;
534 if (other.getOwner() == from.
getOwner())
continue;
535 if (other.isHulk())
continue;
536 if (!other.isTargetable())
continue;
539 if (dist >
getRange(from))
continue;
542 if (dist < other.getCollisionRadius() + 50f) {
561 final Color jitterColor) {
565 public void advance(
float amount, List<InputEventAPI> events) {
573 level = elapsed / in;
574 }
else if (elapsed < in + out) {
575 level = 1f - (elapsed - in) / out;
584 float jitterLevel = level;
585 float maxRangeBonus = 50f;
586 float jitterRangeBonus = jitterLevel * maxRangeBonus;
587 target.
setJitterUnder(
this, jitterColor, jitterLevel, 10, 0f, jitterRangeBonus);
588 target.
setJitter(
this, jitterColor, jitterLevel, 4, 0f, 0 + jitterRangeBonus);
static SoundPlayerAPI getSoundPlayer()
static CombatEngineAPI getCombatEngine()
float computeEffective(float baseValue)
static final String HIGH_FREQUENCY_ATTRACTOR
ShipAPI getLockTarget(ShipAPI from, Vector2f loc)
boolean isMouseInRange(ShipAPI from)
IntervalUtil attractorParticleInterval
Vector2f getTargetedLocation(ShipAPI from)
static float ANTI_FIGHTER_DAMAGE
static String MOTELAUNCHER_HF
IntervalUtil launchInterval
boolean findNewTargetOnUse
boolean isUsable(ShipSystemAPI system, ShipAPI ship)
static String getImpactSoundId(ShipAPI ship)
String getInfoText(ShipSystemAPI system, ShipAPI ship)
static Map< String, MoteData > MOTE_DATA
static Color getEMPColor(ShipAPI ship)
static float getRange(ShipAPI ship)
static float getAntiFighterDamage(ShipAPI ship)
static String getLoopSound(ShipAPI ship)
void apply(MutableShipStatsAPI stats, String id, State state, float effectLevel)
static boolean isHighFrequency(ShipAPI ship)
static float ATTRACTOR_DURATION
void findSlots(ShipAPI ship)
Vector2f getTargetLoc(ShipAPI from)
void calculateTargetData(ShipAPI ship)
void unapply(MutableShipStatsAPI stats, String id)
static float ANTI_FIGHTER_DAMAGE_HF
static float MAX_DIST_FROM_SOURCE_TO_ENGAGE_AS_PD
static String getWeaponId(ShipAPI ship)
WeightedRandomPicker< WeaponSlotAPI > launchSlots
static String MOTELAUNCHER
static Color getJitterColor(ShipAPI ship)
void spawnAttractorParticles(ShipAPI ship)
static int getMaxMotes(ShipAPI ship)
static float ATTRACTOR_DURATION_LOCK
static float MAX_ATTRACTOR_RANGE
static float MAX_DIST_FROM_ATTRACTOR_TO_ENGAGE_AS_PD
StatusData getStatusData(int index, State state, float effectLevel)
boolean isLocationInRange(ShipAPI from, Vector2f loc)
static SharedMoteAIData getSharedData(ShipAPI source)
EveryFrameCombatPlugin createTargetJitterPlugin(final ShipAPI target, final float in, final float out, final Color jitterColor)
void advance(float amount)
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static Vector2f getPointAtRadius(Vector2f from, float r)
static float getAngleInDegrees(Vector2f v)
void playLoop(String id, Object playingEntity, float pitch, float volume, Vector2f loc, Vector2f vel)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)
void addHitParticle(Vector2f loc, Vector2f vel, float size, float brightness, float duration, Color color)
void removeEntity(CombatEntityAPI entity)
Map< String, Object > getCustomData()
CombatEntityAPI spawnProjectile(ShipAPI ship, WeaponAPI weapon, String weaponId, Vector2f point, float angle, Vector2f shipVelocity)
void removePlugin(EveryFrameCombatPlugin plugin)
CombatEntityAPI spawnAsteroid(int size, float x, float y, float dx, float dy)
boolean isMissileAlive(MissileAPI missile)
void spawnMuzzleFlashOrSmoke(ShipAPI ship, WeaponSlotAPI slot, WeaponSpecAPI spec, int barrel, float targetAngle)
void addPlugin(EveryFrameCombatPlugin plugin)
float getElapsedInLastFrame()
List< ShipAPI > getShips()
EmpArcEntityAPI spawnEmpArc(ShipAPI damageSource, Vector2f point, CombatEntityAPI pointAnchor, CombatEntityAPI empTargetEntity, DamageType damageType, float damAmount, float empDamAmount, float maxRange, String impactSoundId, float thickness, Color fringe, Color core)
void setCollisionClass(CollisionClass collisionClass)
float getCollisionRadius()
void setSingleFlickerMode()
void setTargetToShipCenter(Vector2f sourceSlotPos, ShipAPI ship)
void setCoreWidthOverride(float coreWidthOverride)
boolean isOverloadedOrVenting()
EnumSet< CombatEngineLayers > getActiveLayers()
void setWeaponSpec(String weaponId)
void setEmpResistance(int empResistance)
void setMissileAI(MissileAIPlugin ai)
WeaponSpecAPI getWeaponSpec()
StatBonus getSystemRangeBonus()
CombatEntityAPI getEntity()
void setJitterUnder(Object source, Color color, float intensity, int copies, float range)
ShipHullSpecAPI getHullSpec()
MutableShipStatsAPI getMutableStats()
FluxTrackerAPI getFluxTracker()
ShipVariantAPI getVariant()
Vector2f getMouseTarget()
ShipSystemAPI getSystem()
void setJitter(Object source, Color color, float intensity, int copies, float range)
Vector2f getShieldCenterEvenIfNoShield()
List< WeaponSlotAPI > getAllWeaponSlotsCopy()
boolean hasHullMod(String id)
Vector2f computePosition(CombatEntityAPI ship)
float computeMidArcAngle(ShipAPI ship)