1package com.fs.starfarer.api.impl.combat;
4import java.util.Iterator;
7import org.lwjgl.util.vector.Vector2f;
9import com.fs.starfarer.api.GameState;
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.combat.CollisionClass;
12import com.fs.starfarer.api.combat.CombatEngineAPI;
13import com.fs.starfarer.api.combat.CombatEngineLayers;
14import com.fs.starfarer.api.combat.CombatEntityAPI;
15import com.fs.starfarer.api.combat.DamageType;
16import com.fs.starfarer.api.combat.DamagingProjectileAPI;
17import com.fs.starfarer.api.combat.EmpArcEntityAPI;
18import com.fs.starfarer.api.combat.MissileAPI;
19import com.fs.starfarer.api.combat.ShipAPI;
20import com.fs.starfarer.api.combat.ViewportAPI;
21import com.fs.starfarer.api.combat.WeaponAPI;
22import com.fs.starfarer.api.combat.listeners.AdvanceableListener;
23import com.fs.starfarer.api.util.IntervalUtil;
24import com.fs.starfarer.api.util.Misc;
32 public static enum EMPArcHitType {
54 public static class RDRepairRateDebuff
implements AdvanceableListener {
55 public static String DEBUFF_ID =
"reality_disruptor_repair_debuff";
59 public RDRepairRateDebuff(ShipAPI ship) {
62 ship.getMutableStats().getCombatEngineRepairTimeMult().modifyMult(DEBUFF_ID, 1f/
REPAIR_RATE_MULT);
63 ship.getMutableStats().getCombatWeaponRepairTimeMult().modifyMult(DEBUFF_ID, 1f/
REPAIR_RATE_MULT);
66 public void resetDur() {
70 public void advance(
float amount) {
77 "REALITY DISRUPTOR",
"SLOWER REPAIRS: " + (
int)Math.max(1, Math.round(dur)) +
" SEC",
true);
81 ship.removeListener(
this);
82 ship.getMutableStats().getCombatEngineRepairTimeMult().unmodify(DEBUFF_ID);
83 ship.getMutableStats().getCombatWeaponRepairTimeMult().unmodify(DEBUFF_ID);
91 protected DamagingProjectileAPI
proj;
92 protected IntervalUtil
interval =
new IntervalUtil(0.1f, 0.2f);
93 protected IntervalUtil
arcInterval =
new IntervalUtil(0.17f, 0.23f);
111 entity.getLocation().set(
proj.getLocation());
113 entity.getLocation().set(
weapon.getFirePoint(0));
115 super.advance(amount);
119 if (keepSpawningParticles) {
137 proj.getLocation(),
proj.getVelocity());
146 public void render(CombatEngineLayers layer, ViewportAPI viewport) {
148 super.render(layer, viewport,
null);
154 return super.isExpired() && (!keepSpawningParticles || (!
weapon.getShip().isAlive() &&
proj ==
null));
165 if (
proj !=
null &&
proj.isFading()) {
166 return proj.getBrightness();
168 return super.getGlobalAlphaMult();
176 float emp =
proj.getEmpAmount();
177 float dam =
proj.getDamageAmount();
180 float thickness = 20f;
181 float coreWidthMult = 0.67f;
182 Color color =
weapon.getSpec().getGlowColor();
184 if (target !=
null) {
185 EmpArcEntityAPI arc = engine.spawnEmpArc(
proj.getSource(),
proj.getLocation(),
null,
191 "realitydisruptor_emp_impact",
194 new Color(255,255,255,255)
196 arc.setCoreWidthOverride(thickness * coreWidthMult);
201 if (target instanceof ShipAPI) {
202 ShipAPI s = (ShipAPI) target;
203 List<RDRepairRateDebuff> listeners = s.getListeners(RDRepairRateDebuff.class);
204 if (listeners.isEmpty()) {
205 s.addListener(
new RDRepairRateDebuff(s));
207 listeners.get(0).resetDur();
212 Vector2f from =
new Vector2f(
proj.getLocation());
214 EmpArcEntityAPI arc = engine.spawnEmpArcVisual(from,
null, to,
null, thickness, color, Color.white);
215 arc.setCoreWidthOverride(thickness * coreWidthMult);
227 Vector2f from = projectile.getLocation();
228 Vector2f dir = Misc.getUnitVectorAtDegreeAngle((
float) Math.random() * 360f);
230 Vector2f.add(from, dir, dir);
231 dir = Misc.getPointWithinRadius(dir, range * 0.25f);
235 public CombatEntityAPI
findTarget(DamagingProjectileAPI projectile, WeaponAPI
weapon, CombatEngineAPI engine) {
237 Vector2f from = projectile.getLocation();
240 range * 2f, range * 2f);
241 int owner =
weapon.getShip().getOwner();
242 CombatEntityAPI best =
null;
243 float minScore = Float.MAX_VALUE;
244 while (iter.hasNext()) {
245 Object o = iter.next();
246 if (!(o instanceof MissileAPI) &&
248 !(o instanceof ShipAPI))
continue;
249 CombatEntityAPI other = (CombatEntityAPI) o;
250 if (other.getOwner() == owner)
continue;
252 if (other instanceof ShipAPI) {
253 ShipAPI otherShip = (ShipAPI) other;
254 if (otherShip.isHulk())
continue;
255 if (otherShip.isPhased())
continue;
256 if (!otherShip.isTargetable())
continue;
258 if (other.getCollisionClass() == CollisionClass.NONE)
continue;
260 float radius = Misc.getTargetingRadius(from, other,
false);
261 float dist = Misc.getDistance(from, other.getLocation()) - radius - 50f;
262 if (dist > range)
continue;
268 if (score < minScore) {
285 float underSize = 75f;
293 float velMult = 0.2f;
296 size *= 0.25f +
weapon.getChargeLevel() * 0.75f;
303 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(
proj.getFacing() + 180f);
305 if (
proj.getElapsed() > 0.2f) {
306 addDarkParticle(size, in, out, 1.5f, size * 0.5f * velMult, 0f, color);
307 Vector2f offset =
new Vector2f(dir);
308 offset.scale(size * 0.6f + (
float) Math.random() * 0.2f);
309 Vector2f.add(
prev.offset, offset,
prev.offset);
311 if (
proj.getElapsed() > 0.4f) {
312 addDarkParticle(size * 1f, in, out, 1.3f, size * 0.5f * velMult, 0f, color);
313 Vector2f offset =
new Vector2f(dir);
314 offset.scale(size * 1.2f + (
float) Math.random() * 0.2f);
315 Vector2f.add(
prev.offset, offset,
prev.offset);
317 if (
proj.getElapsed() > 0.6f) {
318 addDarkParticle(size * .8f, in, out, 1.1f, size * 0.5f * velMult, 0f, color);
319 Vector2f offset =
new Vector2f(dir);
320 offset.scale(size * 1.6f + (
float) Math.random() * 0.2f);
321 Vector2f.add(
prev.offset, offset,
prev.offset);
324 if (
proj.getElapsed() > 0.8f) {
325 addDarkParticle(size * .8f, in, out, 1.1f, size * 0.5f * velMult, 0f, color);
326 Vector2f offset =
new Vector2f(dir);
327 offset.scale(size * 2.0f + (
float) Math.random() * 0.2f);
328 Vector2f.add(
prev.offset, offset,
prev.offset);
374 float baseDuration = 1.5f;
375 Vector2f vel =
new Vector2f();
380 vel.set(target.getVelocity());
381 if (vel.length() > 100f) {
382 vel.scale(100f / vel.length());
392 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(
proj.getFacing() + 180f);
395 for (
int i = 0; i < numNegative; i++) {
396 float dur = baseDuration + baseDuration * (float) Math.random();
400 if (type == EMPArcHitType.SOURCE) {
403 Vector2f pt = Misc.getPointWithinRadius(point, nSize * 0.5f);
404 Vector2f v = Misc.getUnitVectorAtDegreeAngle((
float) Math.random() * 360f);
405 v.scale(nSize + nSize * (
float) Math.random() * 0.5f);
408 float endSizeMult = 2f;
409 if (type == EMPArcHitType.SOURCE) {
410 pt = Misc.getPointWithinRadius(point, nSize * 0f);
411 Vector2f offset =
new Vector2f(dir);
412 offset.scale(size * 0.2f * i);
413 Vector2f.add(pt, offset, pt);
417 Vector2f.add(vel, v, v);
419 float maxSpeed = nSize * 1.5f * 0.2f;
420 float minSpeed = nSize * 1f * 0.2f;
421 float overMin = v.length() - minSpeed;
423 float durMult = 1f - overMin / (maxSpeed - minSpeed);
424 if (durMult < 0.1f) durMult = 0.1f;
425 dur *= 0.5f + 0.5f * durMult;
432 engine.addNegativeNebulaParticle(pt, v, nSize * 1f, endSizeMult,
434 0.25f / dur, 0f, dur, color);
437 float dur = baseDuration;
438 float rampUp = 0.5f / dur;
440 for (
int i = 0; i < 7; i++) {
441 Vector2f loc =
new Vector2f(point);
442 loc = Misc.getPointWithinRadius(loc, size * 1f);
443 float s = size * 4f * (0.5f + (float) Math.random() * 0.5f);
444 engine.addSwirlyNebulaParticle(loc, vel, s, 1.5f, rampUp, 0f, dur, color,
false);
454 return weapon.getChargeLevel() > 0 &&
weapon.getCooldownRemaining() <= 0;
static SettingsAPI getSettings()
static SoundPlayerAPI getSoundPlayer()
static CombatEngineAPI getCombatEngine()
static GameState getCurrentState()
ParticleData addDarkParticle(float baseSize, float durIn, float durOut, float endSizeMult, float maxDriftVel, float maxAngVel, Color color)
ParticleData addParticle(float baseSize, float durIn, float durOut, float endSizeMult, float maxDriftVel, float maxAngVel, Color color)
void randomizePrevParticleLocation(float maxOffset)
void setSpriteSheetKey(String spriteSheetKey)
void addChargingParticles(WeaponAPI weapon)
RealityDisruptorChargeGlow(WeaponAPI weapon)
void advance(float amount)
static boolean isProjectileExpired(DamagingProjectileAPI proj)
static boolean isWeaponCharging(WeaponAPI weapon)
void attachToProjectile(DamagingProjectileAPI proj)
static float REPAIR_RATE_DEBUFF_DUR
Vector2f pickNoTargetDest(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine)
void render(CombatEngineLayers layer, ViewportAPI viewport)
void spawnEMPParticles(EMPArcHitType type, Vector2f point, CombatEntityAPI target)
float getGlobalAlphaMult()
static float ARC_RATE_MULT
DamagingProjectileAPI proj
static float REPAIR_RATE_MULT
CombatEntityAPI findTarget(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine)
static Color STANDARD_RIFT_COLOR
static Color EXPLOSION_UNDERCOLOR
static Color getColorForDarkening(Color from)
String getSpriteName(String category, String id)
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)