1package com.fs.starfarer.api.impl.combat;
4import java.util.ArrayList;
5import java.util.EnumSet;
8import org.lwjgl.opengl.GL14;
9import org.lwjgl.util.vector.Vector2f;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.combat.ArmorGridAPI;
13import com.fs.starfarer.api.combat.BaseCombatLayeredRenderingPlugin;
14import com.fs.starfarer.api.combat.CombatEngineAPI;
15import com.fs.starfarer.api.combat.CombatEngineLayers;
16import com.fs.starfarer.api.combat.CombatEntityAPI;
17import com.fs.starfarer.api.combat.DamagingProjectileAPI;
18import com.fs.starfarer.api.combat.OnHitEffectPlugin;
19import com.fs.starfarer.api.combat.ShipAPI;
20import com.fs.starfarer.api.combat.ViewportAPI;
21import com.fs.starfarer.api.combat.listeners.ApplyDamageResultAPI;
22import com.fs.starfarer.api.graphics.SpriteAPI;
23import com.fs.starfarer.api.util.FaderUtil;
24import com.fs.starfarer.api.util.IntervalUtil;
25import com.fs.starfarer.api.util.Misc;
27public class DisintegratorEffect extends BaseCombatLayeredRenderingPlugin implements OnHitEffectPlugin {
37 public void onHit(DamagingProjectileAPI projectile, CombatEntityAPI
target, Vector2f point,
boolean shieldHit, ApplyDamageResultAPI damageResult, CombatEngineAPI engine) {
38 if (shieldHit)
return;
39 if (projectile.isFading())
return;
40 if (!(
target instanceof ShipAPI))
return;
42 Vector2f
offset = Vector2f.sub(point,
target.getLocation(),
new Vector2f());
46 CombatEntityAPI e = engine.addLayeredRenderingPlugin(effect);
47 e.getLocation().set(projectile.getLocation());
50 public static class ParticleData {
51 public SpriteAPI sprite;
52 public Vector2f offset =
new Vector2f();
53 public Vector2f vel =
new Vector2f();
54 public float scale = 1f;
55 public float scaleIncreaseRate = 1f;
56 public float turnDir = 1f;
57 public float angle = 1f;
60 public FaderUtil fader;
61 public float elapsed = 0f;
62 public float baseSize;
64 public ParticleData(
float baseSize,
float maxDur,
float endSizeMult) {
67 float i = Misc.random.nextInt(4);
68 float j = Misc.random.nextInt(4);
69 sprite.setTexWidth(0.25f);
70 sprite.setTexHeight(0.25f);
71 sprite.setTexX(i * 0.25f);
72 sprite.setTexY(j * 0.25f);
73 sprite.setAdditiveBlend();
75 angle = (float) Math.random() * 360f;
78 scaleIncreaseRate = endSizeMult / maxDur;
79 if (endSizeMult < 1f) {
80 scaleIncreaseRate = -1f * endSizeMult;
84 this.baseSize = baseSize;
85 turnDir = Math.signum((
float) Math.random() - 0.5f) * 20f * (
float) Math.random();
88 float driftDir = (float) Math.random() * 360f;
89 vel = Misc.getUnitVectorAtDegreeAngle(driftDir);
91 vel.scale(0.25f * baseSize / maxDur * (1f + (
float) Math.random() * 1f));
93 fader =
new FaderUtil(0f, 0.5f, 0.5f);
98 public void advance(
float amount) {
99 scale += scaleIncreaseRate * amount;
101 offset.x += vel.x * amount;
102 offset.y += vel.y * amount;
104 angle += turnDir * amount;
107 if (maxDur - elapsed <= fader.getDurationOut() + 0.1f) {
110 fader.advance(amount);
114 protected List<ParticleData>
particles =
new ArrayList<ParticleData>();
115 protected DamagingProjectileAPI
proj;
120 protected FaderUtil
fader =
new FaderUtil(1f, 0.5f, 0.5f);
127 interval =
new IntervalUtil(0.8f, 1f);
136 protected EnumSet<CombatEngineLayers>
layers = EnumSet.of(CombatEngineLayers.BELOW_INDICATORS_LAYER);
142 public void init(CombatEntityAPI entity) {
149 Vector2f loc =
new Vector2f(
offset);
150 loc = Misc.rotateAroundOrigin(loc,
target.getFacing());
151 Vector2f.add(
target.getLocation(), loc, loc);
152 entity.getLocation().set(loc);
154 List<ParticleData>
remove =
new ArrayList<ParticleData>();
157 if (p.elapsed >= p.maxDur) {
166 fader.advance(amount);
167 volume =
fader.getBrightness();
184 for (
int i = 0; i < num; i++) {
185 ParticleData p =
new ParticleData(30f, 3f + (
float) Math.random() * 2f, 2f);
187 p.offset = Misc.getPointWithinRadius(p.offset, 20f);
191 Vector2f point =
new Vector2f(entity.getLocation());
195 ArmorGridAPI grid =
target.getArmorGrid();
196 int[] cell = grid.getCellAtLocation(point);
197 if (cell ==
null)
return;
199 int gridWidth = grid.getGrid().length;
200 int gridHeight = grid.getGrid()[0].length;
205 float damageDealt = 0f;
206 for (
int i = -2; i <= 2; i++) {
207 for (
int j = -2; j <= 2; j++) {
208 if ((i == 2 || i == -2) && (j == 2 || j == -2))
continue;
210 int cx = cell[0] + i;
211 int cy = cell[1] + j;
213 if (cx < 0 || cx >= gridWidth || cy < 0 || cy >= gridHeight)
continue;
215 float damMult = 1/30f;
216 if (i == 0 && j == 0) {
218 }
else if (i <= 1 && i >= -1 && j <= 1 && j >= -1) {
224 float armorInCell = grid.getArmorValue(cx, cy);
225 float damage = damagePerTick * damMult * damageTypeMult;
226 damage = Math.min(damage, armorInCell);
227 if (damage <= 0)
continue;
229 target.getArmorGrid().setArmorValue(cx, cy, Math.max(0, armorInCell - damage));
230 damageDealt += damage;
234 if (damageDealt > 0) {
235 if (Misc.shouldShowDamageFloaty(
proj.getSource(),
target)) {
236 engine.addFloatingDamageText(point, damageDealt, Misc.FLOATY_ARMOR_DAMAGE_COLOR,
target,
proj.getSource());
238 target.syncWithArmorGridState();
248 public void render(CombatEngineLayers layer, ViewportAPI viewport) {
249 float x = entity.getLocation().x;
250 float y = entity.getLocation().y;
252 Color color =
new Color(100,150,255,35);
253 float b = viewport.getAlphaMult();
255 GL14.glBlendEquation(GL14.GL_FUNC_REVERSE_SUBTRACT);
259 float size = p.baseSize * p.scale;
261 Vector2f loc =
new Vector2f(x + p.offset.x, y + p.offset.y);
263 float alphaMult = 1f;
265 p.sprite.setAngle(p.angle);
266 p.sprite.setSize(size, size);
267 p.sprite.setAlphaMult(b * alphaMult * p.fader.getBrightness());
268 p.sprite.setColor(color);
269 p.sprite.renderAtCenter(loc.x, loc.y);
272 GL14.glBlendEquation(GL14.GL_FUNC_ADD);
277 if (source ==
null ||
target ==
null)
return 1f;
279 float damageTypeMult =
target.getMutableStats().getArmorDamageTakenMult().getModifiedValue();
280 switch (
target.getHullSize()) {
282 damageTypeMult *= source.getMutableStats().getDamageToCapital().getModifiedValue();
285 damageTypeMult *= source.getMutableStats().getDamageToCruisers().getModifiedValue();
288 damageTypeMult *= source.getMutableStats().getDamageToDestroyers().getModifiedValue();
291 damageTypeMult *= source.getMutableStats().getDamageToFrigates().getModifiedValue();
294 damageTypeMult *= source.getMutableStats().getDamageToFighters().getModifiedValue();
297 return damageTypeMult;
static SettingsAPI getSettings()
static SoundPlayerAPI getSoundPlayer()
static CombatEngineAPI getCombatEngine()
void advance(float amount)
EnumSet< CombatEngineLayers > getActiveLayers()
EnumSet< CombatEngineLayers > layers
DisintegratorEffect(DamagingProjectileAPI proj, ShipAPI target, Vector2f offset)
static float getDamageTypeMult(ShipAPI source, ShipAPI target)
static float TOTAL_DAMAGE
void init(CombatEntityAPI entity)
DamagingProjectileAPI proj
void render(CombatEngineLayers layer, ViewportAPI viewport)
List< ParticleData > particles
void onHit(DamagingProjectileAPI projectile, CombatEntityAPI target, Vector2f point, boolean shieldHit, ApplyDamageResultAPI damageResult, CombatEngineAPI engine)
SpriteAPI getSprite(String filename)
void playLoop(String id, Object playingEntity, float pitch, float volume, Vector2f loc, Vector2f vel)