Starsector API
Loading...
Searching...
No Matches
GraviticScanData.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.abilities;
2
3import java.util.ArrayList;
4import java.util.Iterator;
5import java.util.List;
6import java.util.Random;
7
8import org.lwjgl.util.vector.Vector2f;
9
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
13import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
14import com.fs.starfarer.api.campaign.LocationAPI;
15import com.fs.starfarer.api.campaign.OrbitalStationAPI;
16import com.fs.starfarer.api.campaign.PlanetAPI;
17import com.fs.starfarer.api.campaign.SectorEntityToken;
18import com.fs.starfarer.api.impl.campaign.ids.Tags;
19import com.fs.starfarer.api.impl.campaign.velfield.SlipstreamTerrainPlugin2;
20import com.fs.starfarer.api.impl.campaign.velfield.SlipstreamTerrainPlugin2.SlipstreamSegment;
21import com.fs.starfarer.api.util.FaderUtil;
22import com.fs.starfarer.api.util.IntervalUtil;
23import com.fs.starfarer.api.util.Misc;
24
25public class GraviticScanData {
26
27 public static class GSPing {
28 public float arc;
29 public float angle;
30 public float grav;
31 public FaderUtil fader;
32 public boolean withSound = false;
33 public GSPing(float angle, float arc, float grav, float in, float out) {
34 this.arc = arc;
35 this.angle = angle;
36 this.grav = grav;
37 fader = new FaderUtil(0, in, out, false, true);
38 fader.fadeIn();
39 }
40
41 public void advance(float days) {
42 fader.advance(days);
43 if (withSound && fader.getBrightness() >= 0.5f) {
44 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(angle);
45 float dist = 1000f + (1f - Math.min(1f, grav / 200f)) * 1450f;
46 loc.scale(dist);
47 Vector2f.add(loc, Global.getSector().getPlayerFleet().getLocation(), loc);
48 Global.getSoundPlayer().playSound("ui_neutrino_detector_ping", 1, 1, loc, new Vector2f());
49 withSound = false;
50 }
51 }
52
53 public boolean isDone() {
54 return fader.isFadedOut();
55 }
56
57
58 }
59
60 private GraviticScanAbility ability;
61
62
63 private int resolution = 360;
64 transient private float [] data;
65
66
67 private List<GSPing> pings = new ArrayList<GSPing>();
68 //private IntervalUtil noiseInterval = new IntervalUtil(0.01f, 0.02f);
69
70 private IntervalUtil planetInterval = new IntervalUtil(0.01f, 0.01f);
71 private IntervalUtil specialInterval = new IntervalUtil(0.075f, 0.125f);
72 //private IntervalUtil specialInterval = new IntervalUtil(0.15f, 0.25f);
73
75 this.ability = ability;
76 }
77
78 public void advance(float days) {
79 if (ability.getFleet() == null || ability.getFleet().getContainingLocation() == null) return;
80
81// if (ability.getFleet().isInHyperspace()) {
82// data = null;
83// return;
84// }
85
86 Iterator<GSPing> iter = pings.iterator();
87 while (iter.hasNext()) {
88 GSPing ping = iter.next();
89 ping.advance(days);
90 if (ping.isDone()) {
91 iter.remove();
92 }
93 }
94
95
96// noiseInterval.advance(days);
97// if (noiseInterval.intervalElapsed() && false) {
98// float noiseLevel = getNoiseLevel();
99// int num = Math.round(noiseLevel * 10);
100// num = 1;
101// for (int i = 0; i < num; i++) {
102// float angle = (float) Math.random() * 360f;
105// float arc = 5f + 10f * (float) Math.random();
106// float grav = 30f + 80f * (float) Math.random();
107//
110//
111// float in = 0.05f + 0.1f * (float) Math.random();
112// in *= 0.25f;
113// float out = in;
114//
115// GSPing ping = new GSPing(angle, arc, grav, in, out);
116// pings.add(ping);
117// }
118// }
119
120 planetInterval.advance(days);
121 if (planetInterval.intervalElapsed()) {
123 }
124
125 specialInterval.advance(days);
126 if (specialInterval.intervalElapsed()) {
128 }
129
130
131
132 updateData();
133
134 //System.out.println("Pings: " + pings.size());
135 }
136
137
138
139 public void updateData() {
140 data = new float[resolution];
141
142
143 float max = 0f;
144 float incr = 360f / (float) resolution;
145 for (GSPing ping : pings) {
146
147 float b = ping.fader.getBrightness();
148 if (b <= 0) continue;
149
150 //b = (float) Math.sqrt(b);
151 //b *= b;
152
153 float arc = ping.arc;
154 float mid = ping.angle;
155 float half = (float) Math.ceil(0.5f * arc / incr);
156 for (float i = -half; i <= half; i++) {
157 float curr = mid + incr * i;
158 int index = getIndex(curr);
159
160 float intensity = 1f - Math.abs(i / half);
161 intensity *= intensity;
162 float value = ping.grav * intensity * b;
163 data[index] += value;
164 //float min = Math.min(data[index], value);
165 //data[index] = Math.max(data[index], value);
166 //if (data[index] > max) max = data[index];
167 }
168 }
169
170 }
171
172 public float getDataAt(float angle) {
173 if (data == null) return 0f;
174 int index = getIndex(angle);
175 return data[index];
176 }
177
178 public int getIndex(float angle) {
179 angle = Misc.normalizeAngle(angle);
180 int index = (int)Math.floor(resolution * angle/360f);
181 return index;
182 }
183
184 private int initialCount = 0;
185 private List<SectorEntityToken> special = new ArrayList<SectorEntityToken>();
186
187
188 //private float totalForce;
189 public void doSpecialPings() {
190 CampaignFleetAPI fleet = ability.getFleet();
191 boolean abyss = Misc.isInAbyss(fleet);
192 //abyss = false;
193 if (fleet.isInHyperspace() && !abyss) return;
194
195 Vector2f loc = fleet.getLocation();
196 LocationAPI location = fleet.getContainingLocation();
197
198 float neutrinoLowSkipProb = 0.8f;
199 if (special.isEmpty()) {
200// for (SectorEntityToken entity : location.getAsteroids()) {
201// special.add(entity);
202// }
203 for (Object object : location.getEntities(CustomCampaignEntityAPI.class)) {
204 if (object instanceof SectorEntityToken) {
205 SectorEntityToken entity = (SectorEntityToken) object;
206
207 boolean neutrinoHigh = entity.hasTag(Tags.NEUTRINO_HIGH);
208 if (neutrinoHigh) continue;
209
210 if (abyss && !Misc.isInAbyss(entity)) continue;
211
212 boolean neutrino = entity.hasTag(Tags.NEUTRINO);
213 boolean neutrinoLow = entity.hasTag(Tags.NEUTRINO_LOW);
214 boolean station = entity.hasTag(Tags.STATION);
215
216
217
218 if (!neutrino && !neutrinoLow && !station) continue;
219 if (neutrinoLow && (float) Math.random() < neutrinoLowSkipProb) continue;
220
221 special.add(entity);
222 }
223 }
224// for (Object object : location.getEntities(OrbitalStationAPI.class)) {
225// if (object instanceof SectorEntityToken) {
226// SectorEntityToken entity = (SectorEntityToken) object;
227// special.add(entity);
228// }
229// }
230 for (CampaignFleetAPI curr : location.getFleets()) {
231 if (fleet == curr) continue;
232
233 boolean neutrinoHigh = curr.hasTag(Tags.NEUTRINO_HIGH);
234 if (neutrinoHigh) continue;
235
236 if (abyss && !Misc.isInAbyss(fleet)) continue;
237
238 if ((float) Math.random() < neutrinoLowSkipProb) continue;
239 special.add(curr);
240 }
241
242 initialCount = special.size();
243 }
244
245 int batch = (int) Math.ceil(initialCount / 1f);
246 for (int i = 0; i < batch; i++) {
247 if (special.isEmpty()) break;
248
249 SectorEntityToken curr = special.remove(0);
250
251 float dist = Misc.getDistance(loc, curr.getLocation());
252
253 float arc = Misc.computeAngleSpan(curr.getRadius(), dist);
254 arc *= 2f;
255 if (arc < 15) arc = 15;
256 if (arc > 150f) arc = 150f;
257 //arc += 30f;
258 float angle = Misc.getAngleInDegrees(loc, curr.getLocation());
259
260 float g = getGravity(curr);
261 g *= getRangeGMult(dist);
262
263 float in = 0.05f + 0.1f * (float) Math.random();
264 in *= 0.25f;
265 float out = in;
266 out *= 2f;
267 GSPing ping = new GSPing(angle, arc, g, in, out);
268 ping.withSound = true;
269 pings.add(ping);
270 }
271
272
273 long seed = (long) (location.getLocation().x * 1300000 + location.getLocation().y * 3700000 + 1213324234234L);
274 Random random = new Random(seed);
275
276 int numFalse = random.nextInt(5);
277 //System.out.println(numFalse);
278
279 for (int i = 0; i < numFalse; i++) {
280
281 boolean constant = random.nextFloat() > 0.25f;
282 if (!constant && (float) Math.random() < neutrinoLowSkipProb) {
283 random.nextFloat();
284 random.nextFloat();
285 continue;
286 }
287
288 float arc = 15;
289 float angle = random.nextFloat() * 360f;
290 float in = 0.05f + 0.1f * (float) Math.random();
291 in *= 0.25f;
292 float out = in;
293 out *= 2f;
294
295 float g = 80 + random.nextFloat() * 60;
296
297 GSPing ping = new GSPing(angle, arc, g, in, out);
298 ping.withSound = true;
299 pings.add(ping);
300 }
301
302
303 }
304
305 public float getRangeGMult(float range) {
306 range -= 3000;
307 if (range < 0) range = 0;
308
309 float max = 15000;
310 if (range > max) range = max;
311
312
313 return 1f - 0.85f * range / max;
314 }
315
316
318 CampaignFleetAPI fleet = ability.getFleet();
319 Vector2f loc = fleet.getLocation();
320 LocationAPI location = fleet.getContainingLocation();
321
323
324 if (Misc.isInsideSlipstream(fleet) || Misc.isInAbyss(fleet)) return;
325
326 for (CampaignTerrainAPI ter : location.getTerrainCopy()) {
327 if (ter.getPlugin() instanceof SlipstreamTerrainPlugin2) {
328 SlipstreamTerrainPlugin2 plugin = (SlipstreamTerrainPlugin2) ter.getPlugin();
329 if (plugin.containsEntity(fleet)) continue;
330 List<SlipstreamSegment> inRange = new ArrayList<SlipstreamSegment>();
331 List<SlipstreamSegment> near = plugin.getSegmentsNear(loc, range);
332 int skip = 0;
333 for (SlipstreamSegment curr : near) {
334 if (skip > 0) {
335 skip--;
336 continue;
337 }
338 if (curr.bMult <= 0) continue;
339 float dist = Misc.getDistance(loc, curr.loc);
340 if (dist < range) {
341 inRange.add(curr);
342 skip = 5;
343 }
344 }
345 if (!inRange.isEmpty()) {
346 for (SlipstreamSegment curr : inRange) {
347 float dist = Misc.getDistance(loc, curr.loc);
348
349 float arc = Misc.computeAngleSpan(curr.width, dist);
350 arc *= 2f;
351 if (arc > 150f) arc = 150f;
352 if (arc < 20) arc = 20;
353 //arc += 30f;
354 float angle = Misc.getAngleInDegrees(loc, curr.loc);
355 float g = 500f;
356 g *= .1f;
357 g *= getRangeGMult(dist);
358 float in = planetInterval.getIntervalDuration() * 5f;
359 float out = in;
360 GSPing ping = new GSPing(angle, arc, g, in, out);
361 pings.add(ping);
362 }
363 }
364 }
365 }
366
367 }
368
369
371 CampaignFleetAPI fleet = ability.getFleet();
372 Vector2f loc = fleet.getLocation();
373 LocationAPI location = fleet.getContainingLocation();
374
376
377 boolean abyss = Misc.isInAbyss(fleet);
378 if (fleet.isInHyperspace() && !abyss) {
379 return;
380 }
381
382
383// Vector2f netForce = new Vector2f();
384
385 List<SectorEntityToken> all = new ArrayList<SectorEntityToken>(location.getPlanets());
386 for (Object object : location.getEntities(CustomCampaignEntityAPI.class)) {
387 if (object instanceof SectorEntityToken) {
388 SectorEntityToken entity = (SectorEntityToken) object;
389 if (abyss && !Misc.isInAbyss(entity)) continue;
390
391 boolean neutrinoHigh = entity.hasTag(Tags.NEUTRINO_HIGH);
392 if (neutrinoHigh) {
393 all.add(entity);
394 }
395 }
396 }
397 for (CampaignFleetAPI curr : location.getFleets()) {
398 if (fleet == curr) continue;
399 if (abyss && !Misc.isInAbyss(fleet)) continue;
400 boolean neutrinoHigh = curr.hasTag(Tags.NEUTRINO_HIGH);
401 if (neutrinoHigh) {
402 all.add(curr);
403 }
404 }
405
406 for (Object object : location.getEntities(OrbitalStationAPI.class)) {
407 if (object instanceof SectorEntityToken) {
408 SectorEntityToken entity = (SectorEntityToken) object;
409 if (abyss && !Misc.isInAbyss(entity)) continue;
410 all.add(entity);
411 }
412 }
413
414 for (Object object : location.getJumpPoints()) {
415 if (object instanceof SectorEntityToken) {
416 SectorEntityToken entity = (SectorEntityToken) object;
417 if (abyss && !Misc.isInAbyss(entity)) continue;
418 all.add(entity);
419 }
420 }
421
422
423 for (SectorEntityToken entity : all) {
424 if (entity instanceof PlanetAPI) {
425 PlanetAPI planet = (PlanetAPI) entity;
426 if (planet.getSpec().isNebulaCenter()) continue;
427 }
428 if (entity.getRadius() <= 0) continue;
429
430 float dist = Misc.getDistance(loc, entity.getLocation());
431
432 float arc = Misc.computeAngleSpan(entity.getRadius(), dist);
433 arc *= 2f;
434 if (arc > 150f) arc = 150f;
435 if (arc < 20) arc = 20;
436 //arc += 30f;
437 float angle = Misc.getAngleInDegrees(loc, entity.getLocation());
438
439 float g = getGravity(entity);
440 //g /= dist;
441
442 g *= .1f;
443 if (entity.hasTag(Tags.NEUTRINO_HIGH) || entity instanceof OrbitalStationAPI) {
444 g *= 2f;
445 }
446
447 g *= getRangeGMult(dist);
448
449// Vector2f dir = Misc.getUnitVectorAtDegreeAngle(angle);
450// dir.scale(g);
451// Vector2f.add(netForce, dir, netForce);
452// if (Misc.isInArc(90, 30, angle)) {
453// System.out.println("fwefewf");
454// }
455 float in = planetInterval.getIntervalDuration() * 5f;
456 float out = in;
457 GSPing ping = new GSPing(angle, arc, g, in, out);
458 pings.add(ping);
459 }
460
461// for (String key : objectPings.keySet()) {
462// if (!seen.contains(key)) {
463// GSPing ping = objectPings.get(key);
464// ping.fader.setBounceDown(true);
465// }
466// }
467
468 //totalForce = netForce.length();
469 //totalForce = maxG;
470
471 //System.out.println("Pings: " + pings.size());
472 //System.out.println("Noise: " + getNoiseLevel());
473 //System.out.println("Force: " + totalForce);
474 }
475
476// public float getTotalForce() {
477// return totalForce;
478// }
479//
480// public float getNoiseLevel() {
481// //if (true) return 0f;
482//
483// float minForce = 20f;
484// float noiseOneAt = 150;
485//
486// if (totalForce <= minForce) return 0f;
487// float noise = (totalForce - minForce) / (noiseOneAt - minForce);
488// if (noise > 1) noise = 1;
489// return noise;
490// }
491
492 public float getGravity(SectorEntityToken entity) {
493 float g = entity.getRadius();
494
495 if (entity instanceof PlanetAPI) {
496 PlanetAPI planet = (PlanetAPI) entity;
497 //if (g < 200) g = 200;
498
499 g *= 2f;
500
501 if (planet.getSpec().isBlackHole()) {
502 g *= 2f;
503 }
504 }
505
506 if (entity instanceof OrbitalStationAPI) {
507 g *= 4f;
508 if (g > 200) g = 200;
509 }
510
511 if (entity instanceof CustomCampaignEntityAPI) {
512 g *= 4f;
513 if (g > 200) g = 200;
514 }
515
516 if (entity instanceof CampaignFleetAPI) {
517 g *= 2f;
518 if (g > 200) g = 200;
519 }
520
521// if (entity.getName().equals("Asteroid")) {
522// g *= 50f;
523// }
524
525 return g;
526 }
527
528}
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
static SoundPlayerAPI getSoundPlayer()
Definition Global.java:43
static SectorAPI getSector()
Definition Global.java:59
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)