Starsector API
Loading...
Searching...
No Matches
TriadShieldStatsBackup.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.opengl.GL11;
9import org.lwjgl.util.vector.Vector2f;
10
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.combat.BaseCombatLayeredRenderingPlugin;
13import com.fs.starfarer.api.combat.BoundsAPI;
14import com.fs.starfarer.api.combat.CombatEngineLayers;
15import com.fs.starfarer.api.combat.CombatEntityAPI;
16import com.fs.starfarer.api.combat.DamageAPI;
17import com.fs.starfarer.api.combat.MutableShipStatsAPI;
18import com.fs.starfarer.api.combat.ShipAPI;
19import com.fs.starfarer.api.combat.ShipSystemAPI;
20import com.fs.starfarer.api.combat.ViewportAPI;
21import com.fs.starfarer.api.combat.BoundsAPI.SegmentAPI;
22import com.fs.starfarer.api.combat.listeners.DamageTakenModifier;
23import com.fs.starfarer.api.graphics.SpriteAPI;
24import com.fs.starfarer.api.util.FaderUtil;
25import com.fs.starfarer.api.util.FlickerUtilV2;
26import com.fs.starfarer.api.util.Misc;
27
28public class TriadShieldStatsBackup extends BaseShipSystemScript implements DamageTakenModifier {
29
30 public static float SIDE_LENGTH = 16f;
31 public static float INSIDE_ALPHA = 0.25f;
32
33 public static class ShieldPieceConnection {
34 public ShieldPiece from;
35 public ShieldPiece to;
36 public float baseLength = 0f;
37
38 public ShieldPieceConnection(ShieldPiece from, ShieldPiece to) {
39 this.from = from;
40 this.to = to;
41 baseLength = Misc.getDistance(from.offset, to.offset);
42 baseLength *= 0.9f + (float) Math.random() * 0.2f;
43 }
44
45 public void advance(float amount) {
46 Vector2f fLoc = from.getAdjustedOffset();
47 Vector2f tLoc = to.getAdjustedOffset();
48 float length = Misc.getDistance(fLoc, tLoc);
49 float diff = length - baseLength;
50
51 float k = 1f;
52 float accel = diff * k;
53
54 Vector2f dir = Misc.getUnitVectorAtDegreeAngle(Misc.getAngleInDegrees(fLoc, tLoc));
55
56 dir.scale(accel * amount);
57 Vector2f.add(from.vel, dir, from.vel);
58 dir.negate();
59 Vector2f.add(to.vel, dir, to.vel);
60
61
62 float maxOff = 20f;
63 from.off.x += from.vel.x * amount;
64 from.off.y += from.vel.y * amount;
65 if (from.off.length() > maxOff) from.off.scale(maxOff / from.off.length());
66
67 to.off.x += to.vel.x * amount;
68 to.off.y += to.vel.y * amount;
69 if (to.off.length() > maxOff) to.off.scale(maxOff / to.off.length());
70 }
71 }
72
73 public static class ShieldPiece {
74 public ShipAPI ship;
75 public Vector2f offset = new Vector2f();
76
77 public Vector2f off = new Vector2f(); // secondary offset due to movement of individual triangles
78 public Vector2f vel = new Vector2f();
79
80 public SpriteAPI sprite;
81 public boolean upsideDown = false;
82
83 public float side;
84 public Vector2f p1, p2, p3;
85 public float baseAlphaMult = 1f;
86 public float p1Alpha = 1f;
87 public float p2Alpha = 1f;
88 public float p3Alpha = 1f;
89
90 public FaderUtil fader;
91 public FlickerUtilV2 flicker;
92
93 public ShieldPiece(ShipAPI ship, boolean upsideDown, float x, float y, float side) {
94 this.ship = ship;
95 this.side = side;
96 offset.set(x, y);
97 this.upsideDown = upsideDown;
98
99
100 fader = new FaderUtil(0f, 0.25f, 0.25f);
101 fader.setBrightness((float) Math.random() * 1f);
102 fader.setBounce(true, true);
103 fader.fadeIn();
104
105 flicker = new FlickerUtilV2();
106
107 //sprite = Global.getSettings().getSprite("misc", "fx_shield_piece");
108 sprite = Global.getSettings().getSprite("graphics/hud/line8x8.png");
109 //sprite = Global.getSettings().getSprite("graphics/hud/line32x32.png");
110
111 // updside down means the flat side is on the left
112 // p1 is always the lone point, p2->p3 the flat side on the left/right
113 // triangles are arranged as if ship is pointed at a 0 degree angle, i.e. facing right
114 float height = (float) (side * Math.sqrt(3f) / 2f);
115 if (upsideDown) {
116 p1 = new Vector2f(x + height/2f, y);
117 p2 = new Vector2f(x - height/2f - 1, y - side/2f);
118 p3 = new Vector2f(x - height/2f - 1, y + side/2f);
119 } else {
120 p1 = new Vector2f(x - height/2f, y);
121 p2 = new Vector2f(x + height/2f, y - side/2f);
122 p3 = new Vector2f(x + height/2f, y + side/2f);
123 }
124 updatePointAlpha();
125 }
126
127 public void updatePointAlpha() {
128 //if (true) return;
129 BoundsAPI bounds = ship.getExactBounds();
130 bounds.update(new Vector2f(0, 0), 0f);
131 p1Alpha = getPointAlpha(p1);
132 p2Alpha = getPointAlpha(p2);
133 p3Alpha = getPointAlpha(p3);
134
135 baseAlphaMult = Math.max(p1Alpha, p2Alpha);
136 baseAlphaMult = Math.max(baseAlphaMult, p3Alpha);
137// if (baseAlphaMult > 0) {
138// p1Alpha = p2Alpha = p3Alpha = 1f;
139// }
140 }
141 public float getPointAlpha(Vector2f p) {
142 BoundsAPI bounds = ship.getExactBounds();
143
144 float minDist = Float.MAX_VALUE;
145 List<Vector2f> boundsPoints = new ArrayList<Vector2f>();
146 for (SegmentAPI segment : bounds.getSegments()) {
147 Vector2f n = Misc.closestPointOnSegmentToPoint(segment.getP1(), segment.getP2(), p);
148 float dist = Misc.getDistance(n, p);
149 if (dist < minDist) minDist = dist;
150
151 boundsPoints.add(segment.getP1());
152 }
153 boundsPoints.add(bounds.getSegments().get(bounds.getSegments().size() - 1).getP2());
154
155 float minAlphaAt = SIDE_LENGTH * 1f;
156 float minAlpha = 0f;
157 boolean inBounds = Misc.isPointInBounds(p, boundsPoints);
158 if (inBounds) {
159 //if (true) return 1f;
160// minAlpha = INSIDE_ALPHA;
161// minAlpha = 0.25f;
162 minAlphaAt = SIDE_LENGTH * 2f;
163 minAlphaAt = 0f;
164 }
165
166 if (minDist > minAlphaAt) {
167 return minAlpha;
168 }
169
170
171 return Math.max(minAlpha, 1f - Math.min(1f, minDist / (minAlphaAt * 2f)));
172
173 //return Math.max(minAlpha, 1f - minDist / minAlphaAt);
174 }
175
176 public Vector2f getAdjustedOffset() {
177 return Vector2f.add(offset, off, new Vector2f());
178 }
179
180 public Vector2f getCenter() {
181 Vector2f result = new Vector2f(offset);
182 Misc.rotateAroundOrigin(result, ship.getFacing());
183 Vector2f.add(ship.getLocation(), result, result);
184 return result;
185 }
186
187 public void advance(float amount) {
188 fader.advance(amount * (0.5f + 0.5f * (float) Math.random()));
189 //flicker.advance(amount);
190 }
191
196 public void render(float alphaMult) {
197 Color color = new Color(255, 165, 100, 255);
198 color = new Color(100, 165, 255, 255);
199 //color = new Color(0, 0, 255, 255);
200 //color = Misc.scaleAlpha(color, 0.5f);
201
202// float size = 14f;
203// float x = offset.x;
204// float y = offset.y;
205// sprite.setSize(size, size);
206// sprite.setColor(color);
207// sprite.setAdditiveBlend();
208// sprite.setNormalBlend();
209// sprite.setAngle(-90);
210// if (upsideDown) {
211// sprite.setAngle(-90 + 180f);
212// }
213// sprite.setAlphaMult(alphaMult);
214// sprite.renderAtCenter(x, y);
215
216 if (true) {
217// p1Alpha = p2Alpha = p3Alpha = 1f;
218// baseAlphaMult = 1f;
219// alphaMult = 1f;
220 GL11.glPushMatrix();
221 GL11.glTranslatef(off.x, off.y, 0f);
222
223 for (int i = 0; i < 2; i++) {
224 GL11.glEnable(GL11.GL_TEXTURE_2D);
225 sprite.bindTexture();
226 GL11.glEnable(GL11.GL_BLEND);
227 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
228// if (i == 0) {
229// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
230// }
231
232// float sin = (float) Math.sin(Math.toRadians(30f));
233// float cos = (float) Math.sin(Math.toRadians(30f));
234 float t = 9f;
235 float a = 0.25f;
236 if (i == 1) {
237 t = 4f;
238 a = 1f;
239 }
240
241 //float in = (float) (Math.sin(Math.toRadians(30f)) * t);
242 if (upsideDown) {
243 GL11.glBegin(GL11.GL_QUAD_STRIP);
244
245 Misc.setColor(color, alphaMult * p1Alpha * a);
246 GL11.glTexCoord2f(0f, 0f);
247 GL11.glVertex2f(p1.x, p1.y);
248 GL11.glTexCoord2f(0f, 1f);
249 GL11.glVertex2f(p1.x - t, p1.y);
250
251 Misc.setColor(color, alphaMult * p2Alpha * a);
252 GL11.glTexCoord2f(0f, 0f);
253 GL11.glVertex2f(p2.x, p2.y);
254 GL11.glTexCoord2f(0f, 1f);
255 GL11.glVertex2f(p2.x + t * 0.5f, p2.y + t);
256
257 Misc.setColor(color, alphaMult * p3Alpha * a);
258 GL11.glTexCoord2f(0f, 0f);
259 GL11.glVertex2f(p3.x, p3.y);
260 GL11.glTexCoord2f(0f, 1f);
261 GL11.glVertex2f(p3.x + t * 0.5f, p3.y - t);
262
263 Misc.setColor(color, alphaMult * p1Alpha * a);
264 GL11.glTexCoord2f(0f, 0f);
265 GL11.glVertex2f(p1.x, p1.y);
266 GL11.glTexCoord2f(0f, 1f);
267 GL11.glVertex2f(p1.x - t, p1.y);
268
269 GL11.glEnd();
270 } else {
271 GL11.glBegin(GL11.GL_QUAD_STRIP);
272
273 Misc.setColor(color, alphaMult * p1Alpha * a);
274 GL11.glTexCoord2f(0f, 0f);
275 GL11.glVertex2f(p1.x, p1.y);
276 GL11.glTexCoord2f(0f, 1f);
277 GL11.glVertex2f(p1.x + t, p1.y);
278
279 Misc.setColor(color, alphaMult * p2Alpha * a);
280 GL11.glTexCoord2f(0f, 0f);
281 GL11.glVertex2f(p2.x, p2.y);
282 GL11.glTexCoord2f(0f, 1f);
283 GL11.glVertex2f(p2.x - t * 0.5f, p2.y + t);
284
285 Misc.setColor(color, alphaMult * p3Alpha * a);
286 GL11.glTexCoord2f(0f, 0f);
287 GL11.glVertex2f(p3.x, p3.y);
288 GL11.glTexCoord2f(0f, 1f);
289 GL11.glVertex2f(p3.x - t * 0.5f, p3.y - t);
290
291 Misc.setColor(color, alphaMult * p1Alpha * a);
292 GL11.glTexCoord2f(0f, 0f);
293 GL11.glVertex2f(p1.x, p1.y);
294 GL11.glTexCoord2f(0f, 1f);
295 GL11.glVertex2f(p1.x + t, p1.y);
296
297 GL11.glEnd();
298 }
299 }
300
301 GL11.glPopMatrix();
302 return;
303 }
304
305
306 GL11.glDisable(GL11.GL_TEXTURE_2D);
307 GL11.glEnable(GL11.GL_BLEND);
308 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
309 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
310
311// GL11.glColor4ub((byte)color.getRed(),
312// (byte)color.getGreen(),
313// (byte)color.getBlue(),
314// (byte)(color.getAlpha() * alphaMult));
315
316 alphaMult *= baseAlphaMult;
317 //alphaMult *= 0.67f + 0.33f * fader.getBrightness();
318
319
320 GL11.glBegin(GL11.GL_TRIANGLES);
321 {
322 float i = 0f;
323 float j = 0f;
324// alphaMult *= 0.2f;
325// float incr = 0.5f;
326// for (float i = -incr; i <= incr; i+=incr) {
327// for (float j = -incr; j <= incr; j+=incr) {
328 Misc.setColor(color, alphaMult * p1Alpha);
329 GL11.glVertex2f(p1.x + i, p1.y + j);
330 Misc.setColor(color, alphaMult * p2Alpha);
331 GL11.glVertex2f(p2.x + i, p2.y + j);
332 Misc.setColor(color, alphaMult * p3Alpha);
333 GL11.glVertex2f(p3.x + i, p3.y + j);
334// }
335// }
336 }
337 GL11.glEnd();
338
339// GL11.glBegin(GL11.GL_TRIANGLES);
340// {
341// Misc.setColor(color, alphaMult * p1Alpha);
342// GL11.glVertex2f(p1.x, p1.y);
343// Misc.setColor(color, alphaMult * p2Alpha);
344// GL11.glVertex2f(p2.x, p2.y);
345// Misc.setColor(color, alphaMult * p3Alpha);
346// GL11.glVertex2f(p3.x, p3.y);
347// }
348// GL11.glEnd();
349
350// GL11.glBegin(GL11.GL_QUADS);
351// {
352// GL11.glVertex2f(x, y);
353// GL11.glVertex2f(x, y + h);
354// GL11.glVertex2f(x + w, y + h);
355// GL11.glVertex2f(x + w, y);
356// }
357// GL11.glEnd();
358 }
359 }
360
361
362 public static class TriadShieldVisuals extends BaseCombatLayeredRenderingPlugin {
363 public ShipAPI ship;
364 public TriadShieldStatsBackup script;
365 public List<ShieldPiece> pieces = new ArrayList<ShieldPiece>();
366 public List<ShieldPieceConnection> connections = new ArrayList<ShieldPieceConnection>();
367
368 public TriadShieldVisuals(ShipAPI ship, TriadShieldStatsBackup script) {
369 this.ship = ship;
370 this.script = script;
371 addShieldPieces();
372 }
373
374 public void addShieldPieces() {
375 pieces.clear();
376
377 SIDE_LENGTH = 20f;
378 //SIDE_LENGTH = 10f;
379 //SIDE_LENGTH = 120f;
380
381 float side = SIDE_LENGTH;
382 float height = (float) (side * Math.sqrt(3f) / 2f);
383 float centerFromBottom = (float) (Math.sin(Math.toRadians(30f)) * height);
384 //centerFromBottom = side/2f;
385 int gridHeight = (int) (ship.getCollisionRadius() / side) * 2;
386 if (gridHeight / 2 != 0) gridHeight++;
387 if (gridHeight < 6) gridHeight = 6;
388 int gridWidth = (int) (ship.getCollisionRadius() / height) * 2;
389 if (gridWidth / 2 != 0) gridWidth++;
390 if (gridWidth < 6) gridWidth = 6;
391 for (int i = -gridWidth/2; i < gridWidth/2; i++) {
392 for (int j = -gridHeight/2; j < gridHeight/2; j++) {
393 float lowX = i * height + height/2f;
394 float highX = (i + 1) * height + height/2f;
395 float centerY = j * side + side/2f;
396 ShieldPiece piece = new ShieldPiece(ship, true, lowX + centerFromBottom, centerY, side - 2f);
397 if (piece.baseAlphaMult > 0) {
398 pieces.add(piece);
399 }
400
401 if (j != gridHeight/2 - 1) {
402 centerY += side/2f;
403 piece = new ShieldPiece(ship, false, highX - centerFromBottom, centerY, side - 2f);
404 if (piece.baseAlphaMult > 0) {
405 pieces.add(piece);
406 }
407 }
408 }
409 }
410
411 float maxDist = SIDE_LENGTH * 1.2f;
412 for (int i = 0; i < pieces.size() - 1; i++) {
413 ShieldPiece curr = pieces.get(i);
414 for (int j = i + 1; j < pieces.size(); j++) {
415 ShieldPiece other = pieces.get(j);
416 if (curr == other) continue;
417 if (Misc.getDistance(curr.offset, other.offset) > maxDist) continue;
418
419 ShieldPieceConnection conn = new ShieldPieceConnection(curr, other);
420 connections.add(conn);
421 }
422 }
423 }
424
425 @Override
426 public EnumSet<CombatEngineLayers> getActiveLayers() {
427 return EnumSet.of(CombatEngineLayers.ABOVE_SHIPS_AND_MISSILES_LAYER);
428 }
429 @Override
430 public boolean isExpired() {
431 return false;
432 }
433 @Override
434 public float getRenderRadius() {
435 return ship.getCollisionRadius() + 100f;
436 }
437
438 @Override
439 public void advance(float amount) {
440 entity.getLocation().set(ship.getLocation());
441 if (Global.getCombatEngine().isPaused()) return;
442
443 for (ShieldPiece piece : pieces) {
444 piece.advance(amount);
445 }
446
447 for (ShieldPieceConnection conn : connections) {
448 conn.advance(amount);
449 }
450 }
451
452 @Override
453 public void render(CombatEngineLayers layer, ViewportAPI viewport) {
454 float alphaMult = viewport.getAlphaMult();
455
456 ShipSystemAPI system = ship.getPhaseCloak();
457 if (system == null) system = ship.getSystem();
458 alphaMult *= system.getEffectLevel();
459 if (alphaMult <= 0f) return;
460
461 GL11.glPushMatrix();
462 GL11.glTranslatef(ship.getLocation().x, ship.getLocation().y, 0);
463 GL11.glRotatef(ship.getFacing(), 0, 0, 1);
464
465 for (ShieldPiece piece : pieces) {
466 piece.render(alphaMult);
467 }
468 GL11.glPopMatrix();
469
470// Color color = Color.red;
471// color = Misc.scaleAlpha(color, 0.5f);
472//
473// float x = ship.getLocation().x - ship.getCollisionRadius() * 0.5f;
474// float y = ship.getLocation().y - ship.getCollisionRadius() * 0.5f;
475// float w = ship.getCollisionRadius();
476// float h = ship.getCollisionRadius();
477//
478// GL11.glDisable(GL11.GL_TEXTURE_2D);
479// GL11.glEnable(GL11.GL_BLEND);
480// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
481//
482//
483// GL11.glColor4ub((byte)color.getRed(),
484// (byte)color.getGreen(),
485// (byte)color.getBlue(),
486// (byte)(color.getAlpha() * alphaMult));
487//
488// GL11.glBegin(GL11.GL_QUADS);
489// {
490// GL11.glVertex2f(x, y);
491// GL11.glVertex2f(x, y + h);
492// GL11.glVertex2f(x + w, y + h);
493// GL11.glVertex2f(x + w, y);
494// }
495// GL11.glEnd();
496 }
497 }
498
499 protected TriadShieldVisuals visuals = null;
500
501 public String modifyDamageTaken(Object param, CombatEntityAPI target, DamageAPI damage, Vector2f point, boolean shieldHit) {
502 return null;
503 }
504
505 public void apply(MutableShipStatsAPI stats, String id, State state, float effectLevel) {
506 ShipAPI ship = null;
507 boolean player = false;
508 if (stats.getEntity() instanceof ShipAPI) {
509 ship = (ShipAPI) stats.getEntity();
510 player = ship == Global.getCombatEngine().getPlayerShip();
511 id = id + "_" + ship.getId();
512 } else {
513 return;
514 }
515
516 if (visuals == null) {
517 visuals = new TriadShieldVisuals(ship, this);
518 Global.getCombatEngine().addLayeredRenderingPlugin(visuals);
519 ship.addListener(this);
520 }
521
522
523
524 if (Global.getCombatEngine().isPaused()) {
525 return;
526 }
527
528 if (state == State.COOLDOWN || state == State.IDLE) {
529 unapply(stats, id);
530 return;
531 }
532
533 ShipSystemAPI system = ship.getPhaseCloak();
534 if (system == null) system = ship.getSystem();
535
536
537 if (state == State.IN || state == State.ACTIVE) {
538
539 } else if (state == State.OUT) {
540
541 }
542 }
543
544
545 public void unapply(MutableShipStatsAPI stats, String id) {
546 ShipAPI ship = null;
547 boolean player = false;
548 if (stats.getEntity() instanceof ShipAPI) {
549 ship = (ShipAPI) stats.getEntity();
550 player = ship == Global.getCombatEngine().getPlayerShip();
551 id = id + "_" + ship.getId();
552 } else {
553 return;
554 }
555
556
557 }
558
559 public StatusData getStatusData(int index, State state, float effectLevel) {
560 return null;
561 }
562
563}
static SettingsAPI getSettings()
Definition Global.java:51
static CombatEngineAPI getCombatEngine()
Definition Global.java:63
void apply(MutableShipStatsAPI stats, String id, State state, float effectLevel)
String modifyDamageTaken(Object param, CombatEntityAPI target, DamageAPI damage, Vector2f point, boolean shieldHit)
StatusData getStatusData(int index, State state, float effectLevel)
SpriteAPI getSprite(String filename)