Starsector API
Loading...
Searching...
No Matches
CryoblasterEffect.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.combat;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.EnumSet;
6import java.util.List;
7
8import org.lwjgl.util.vector.Vector2f;
9
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.combat.BaseCombatLayeredRenderingPlugin;
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.DamagingProjectileAPI;
16import com.fs.starfarer.api.combat.OnFireEffectPlugin;
17import com.fs.starfarer.api.combat.OnHitEffectPlugin;
18import com.fs.starfarer.api.combat.ShipAPI;
19import com.fs.starfarer.api.combat.ViewportAPI;
20import com.fs.starfarer.api.combat.WeaponAPI;
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.Misc;
25
26public class CryoblasterEffect extends BaseCombatLayeredRenderingPlugin implements OnFireEffectPlugin,
27 OnHitEffectPlugin {
28
30 }
31
32 public void onHit(DamagingProjectileAPI projectile, CombatEntityAPI target, Vector2f point, boolean shieldHit, ApplyDamageResultAPI damageResult, CombatEngineAPI engine) {
33 Color color = projectile.getProjectileSpec().getFringeColor();
34 color = Misc.setAlpha(color, 100);
35
36 Vector2f vel = new Vector2f();
37 if (target instanceof ShipAPI) {
38 vel.set(target.getVelocity());
39 }
40
41 float sizeMult = Misc.getHitGlowSize(100f, projectile.getDamage().getBaseDamage(), damageResult) / 100f;
42
43 for (int i = 0; i < 7; i++) {
44 //float size = projectile.getProjectileSpec().getWidth() * (0.75f + (float) Math.random() * 0.5f);
45 float size = 40f * (0.75f + (float) Math.random() * 0.5f);
46
47 float dur = 1f;
48 //dur = 0.25f;
49 float rampUp = 0f;
50 Color c = Misc.scaleAlpha(color, projectile.getBrightness());
51 engine.addNebulaParticle(point, vel, size, 5f + 3f * sizeMult,
52 rampUp, 0f, dur, c, true);
53 }
54 }
55
56 public void onFire(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine) {
57 CryoblasterEffect trail = new CryoblasterEffect(projectile);
58 CombatEntityAPI e = engine.addLayeredRenderingPlugin(trail);
59 e.getLocation().set(projectile.getLocation());
60 }
61
62
63 public static class ParticleData {
64 public SpriteAPI sprite;
65 public Vector2f offset = new Vector2f();
66 public Vector2f vel = new Vector2f();
67 public float scale = 1f;
68 public DamagingProjectileAPI proj;
69 public float scaleIncreaseRate = 1f;
70 public float turnDir = 1f;
71 public float angle = 1f;
72
73 public float maxDur;
74 public Vector2f origVel;
75 public FaderUtil fader;
76 public Vector2f dirVelChange;
77
78 public ParticleData(DamagingProjectileAPI proj) {
79 this.proj = proj;
80 sprite = Global.getSettings().getSprite("misc", "nebula_particles");
81 //sprite = Global.getSettings().getSprite("misc", "dust_particles");
82 float i = Misc.random.nextInt(4);
83 float j = Misc.random.nextInt(4);
84 sprite.setTexWidth(0.25f);
85 sprite.setTexHeight(0.25f);
86 sprite.setTexX(i * 0.25f);
87 sprite.setTexY(j * 0.25f);
88 sprite.setAdditiveBlend();
89
90 angle = (float) Math.random() * 360f;
91
92 maxDur = proj.getWeapon().getRange() / proj.getWeapon().getProjectileSpeed();
93 scaleIncreaseRate = 2.5f / maxDur;
94 scale = 1f;
95
96 turnDir = Math.signum((float) Math.random() - 0.5f) * 30f * (float) Math.random();
97 //turnDir = 0f;
98
99 float driftDir = proj.getFacing() + 180f + ((float) Math.random() * 30f - 15f);
100 vel = Misc.getUnitVectorAtDegreeAngle(driftDir);
101 //vel.scale(proj.getProjectileSpec().getLength() / maxDur * (0f + (float) Math.random() * 3f));
102 vel.scale(80f / maxDur * (0f + (float) Math.random() * 3f));
103
104 origVel = new Vector2f(vel);
105 dirVelChange = Misc.getUnitVectorAtDegreeAngle(proj.getFacing() + 180f);
106
107// offset.x += vel.x * 1f;
108// offset.y += vel.y * 1f;
109 fader = new FaderUtil(0f, 0.25f, 0.05f);
110 fader.fadeIn();
111 }
112
113 public void advance(float amount) {
114 scale += scaleIncreaseRate * amount;
115
116// if (proj.didDamage()) {
117// vel.set(origVel);
118// //fader.fadeOut();
119// }
120
121 offset.x += vel.x * amount;
122 offset.y += vel.y * amount;
123
124 if (!proj.didDamage()) {
125 float speed = vel.length();
126 if (speed > 0) {
127 float speedIncrease = proj.getMoveSpeed() / maxDur * 0.5f;
128 Vector2f dir = new Vector2f(dirVelChange);
129 dir.scale(speedIncrease * amount);
130 Vector2f.add(vel, dir, vel);
131 }
132 }
133
134 angle += turnDir * amount;
135
136 fader.advance(amount);
137 }
138 }
139
140 protected List<ParticleData> particles = new ArrayList<ParticleData>();
141
142 protected DamagingProjectileAPI proj;
143 protected Vector2f projVel;
144 protected Vector2f projLoc;
145 public CryoblasterEffect(DamagingProjectileAPI proj) {
146 this.proj = proj;
147
148 projVel = new Vector2f(proj.getVelocity());
149 projLoc = new Vector2f(proj.getLocation());
150
151 int num = 30;
152 for (int i = 0; i < num; i++) {
153 particles.add(new ParticleData(proj));
154 }
155
156 float index = 0;
157 for (ParticleData p : particles) {
158 //p.offset = Misc.getPointWithinRadius(p.offset, width * 0.5f);
159 p.offset = Misc.getPointWithinRadius(p.offset, 20f);
160 index++;
161 }
162 }
163
164 public float getRenderRadius() {
165 return 700f;
166 }
167
168
169 protected EnumSet<CombatEngineLayers> layers = EnumSet.of(CombatEngineLayers.ABOVE_SHIPS_AND_MISSILES_LAYER);
170 @Override
171 public EnumSet<CombatEngineLayers> getActiveLayers() {
172 return layers;
173 }
174
175 public void init(CombatEntityAPI entity) {
176 super.init(entity);
177 }
178
179 protected boolean resetTrailSpeed = false;
180 public void advance(float amount) {
181 if (Global.getCombatEngine().isPaused()) return;
182
183 entity.getLocation().set(proj.getLocation());
184
185 float max = 0f;
186 for (ParticleData p : particles) {
187 p.advance(amount);
188 max = Math.max(max, p.offset.lengthSquared());
189 }
190
191 // BALLISTIC_AS_BEAM don't get some stuff set right away, catch it in the first few frames
192 // but after that the particles move independently
193 if (proj.getElapsed() < 0.1f) {
194 projVel.set(proj.getVelocity());
195 projLoc.set(proj.getLocation());
196 } else {
197 projLoc.x += projVel.x * amount;
198 projLoc.y += projVel.y * amount;
199
200 if (proj.didDamage()) {
201 if (!resetTrailSpeed) {
202 for (ParticleData p : particles) {
203 Vector2f.add(p.vel, projVel, p.vel);
204 }
205 projVel.scale(0f);
206 resetTrailSpeed = true;
207 }
208 for (ParticleData p : particles) {
209 float dist = p.offset.length();
210 p.vel.scale(Math.min(1f, dist / 100f));
211 }
212 }
213 }
214 }
215
216
217 public boolean isExpired() {
218 return proj.isExpired() || !Global.getCombatEngine().isEntityInPlay(proj);
219 }
220
221 public void render(CombatEngineLayers layer, ViewportAPI viewport) {
222// float x = entity.getLocation().x;
223// float y = entity.getLocation().y;
224 float x = projLoc.x;
225 float y = projLoc.y;
226
227 Color color = proj.getProjectileSpec().getFringeColor();
228 color = Misc.setAlpha(color, 30);
229 float b = proj.getBrightness();
230 b *= viewport.getAlphaMult();
231
232// Vector2f farAhead = Misc.getUnitVectorAtDegreeAngle(proj.getFacing());
233// farAhead.scale(10000f);
234// Vector2f.add(proj.getLocation(), farAhead, farAhead);
235
236 for (ParticleData p : particles) {
237 //float size = proj.getProjectileSpec().getWidth() * 0.6f;
238 float size = 25f;
239 size *= p.scale;
240
241 Vector2f loc = new Vector2f(x + p.offset.x, y + p.offset.y);
242
243 float alphaMult = 1f;
244 //float dParticle = Misc.getDistance(farAhead, loc);
245
246 float a = alphaMult;
247
248 p.sprite.setAngle(p.angle);
249 p.sprite.setSize(size, size);
250 p.sprite.setAlphaMult(b * a * p.fader.getBrightness());
251 p.sprite.setColor(color);
252 p.sprite.renderAtCenter(loc.x, loc.y);
253 }
254 }
255
256}
257
258
259
260
static SettingsAPI getSettings()
Definition Global.java:51
static CombatEngineAPI getCombatEngine()
Definition Global.java:63
void render(CombatEngineLayers layer, ViewportAPI viewport)
void onFire(DamagingProjectileAPI projectile, WeaponAPI weapon, CombatEngineAPI engine)
void onHit(DamagingProjectileAPI projectile, CombatEntityAPI target, Vector2f point, boolean shieldHit, ApplyDamageResultAPI damageResult, CombatEngineAPI engine)
SpriteAPI getSprite(String filename)