Starsector API
Loading...
Searching...
No Matches
BreadcrumbSpecial.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special;
2
3import org.lwjgl.util.vector.Vector2f;
4
5import com.fs.starfarer.api.Global;
6import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
7import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
8import com.fs.starfarer.api.campaign.InteractionDialogAPI;
9import com.fs.starfarer.api.campaign.JumpPointAPI;
10import com.fs.starfarer.api.campaign.LocationAPI;
11import com.fs.starfarer.api.campaign.PlanetAPI;
12import com.fs.starfarer.api.campaign.SectorEntityToken;
13import com.fs.starfarer.api.campaign.StarSystemAPI;
14import com.fs.starfarer.api.combat.ShipAPI.HullSize;
15import com.fs.starfarer.api.combat.ShipVariantAPI;
16import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin;
17import com.fs.starfarer.api.impl.campaign.ids.Entities;
18import com.fs.starfarer.api.impl.campaign.ids.Tags;
19import com.fs.starfarer.api.impl.campaign.ids.Terrain;
20import com.fs.starfarer.api.impl.campaign.intel.misc.BreadcrumbIntelV2;
21import com.fs.starfarer.api.impl.campaign.intel.misc.SalvorsTallyIntel;
22import com.fs.starfarer.api.impl.campaign.procgen.Constellation;
23import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageSpecialInteraction.SalvageSpecialData;
24import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.SalvageSpecialInteraction.SalvageSpecialPlugin;
25import com.fs.starfarer.api.impl.campaign.terrain.DebrisFieldTerrainPlugin;
26import com.fs.starfarer.api.util.CountingMap;
27import com.fs.starfarer.api.util.Misc;
28
30
31
32 public static class BreadcrumbSpecialData implements SalvageSpecialData {
33 public String targetId = null;
34 public String targetName = null;
35 public BreadcrumbSpecialData(String targetId) {
36 this.targetId = targetId;
37 }
38
39 public SalvageSpecialPlugin createSpecialPlugin() {
40// if (Global.getSector().getEntityById(targetId) instanceof PlanetAPI) {
41// return new SurveyDataSpecial();
42// }
43 return new BreadcrumbSpecial();
44 }
45 }
46
47 private BreadcrumbSpecialData data;
48
50 }
51
52
53 @Override
54 public void init(InteractionDialogAPI dialog, Object specialData) {
55 super.init(dialog, specialData);
56
57 data = (BreadcrumbSpecialData) specialData;
58
59 initEntityLocation();
60 }
61
62 private void initEntityLocation() {
63 if (data.targetId == null) {
65 return;
66 }
67
68 SectorEntityToken target = Global.getSector().getEntityById(data.targetId);
69 if (target == null) {
71 return;
72 }
73
74 // already discovered
75 if (!target.hasSensorProfile() && !target.isDiscoverable() && !(target instanceof PlanetAPI)) {
77 return;
78 }
79
80 if (target instanceof PlanetAPI && !Misc.hasUnexploredRuins(target.getMarket())) {
82 return;
83 }
84
85
86 String targetName = getNameWithAOrAn(target, data.targetName, true, false);
87 String targetNameUC = getNameWithAOrAn(target, data.targetName, false, true);
88 //String entityName = getNameWithAOrAn(entity, null);
89 String located = getLocatedString(target, true);
90
91 String nameForTitle = targetNameUC.substring(targetNameUC.indexOf(" ") + 1);
92 //if (target.getCu)
93 String subject = getString("Location: " + nameForTitle);
94 if (target instanceof PlanetAPI && target.getMarket() != null) {
95 subject = "Location: " + Misc.getRuinsSpec(target.getMarket()).getName();
96 //subject += " Ruins";
97 }
98
99
100 String text1 = "The $shortName's memory banks are partially accessible, and ";
101 text1 += "contain information indicating that " + targetName + " is " + located + ".";
102
103 String text1ForIntel = "While exploring $aOrAn $nameInText, your crews found a " +
104 "partially accessible memory bank " +
105 "containing information that indicates " + targetName + " is " + located + ".";
106
107 boolean debris = Entities.DEBRIS_FIELD_SHARED.equals(entity.getCustomEntityType());
108 if (debris) {
109 text1 = "Your salvage crews find a functional memory bank in the debris. It contains information " +
110 "indicating that " + targetName.toLowerCase() + " is " + located + ".";
111 }
112
113
114 if (target.getCustomPlugin() instanceof DerelictShipEntityPlugin) {
115 DerelictShipEntityPlugin dsep = (DerelictShipEntityPlugin) target.getCustomPlugin();
116 ShipVariantAPI variant = dsep.getData().ship.variant;
117 if (variant == null && dsep.getData().ship.variantId != null) {
118 variant = Global.getSettings().getVariant(dsep.getData().ship.variantId);
119 }
120 if (variant != null) {
121 String size = null;
122 if (variant.getHullSize() == HullSize.FRIGATE ||
123 variant.getHullSize() == HullSize.DESTROYER) {
124 size = "Based on the information, it's likely the ship is small, a frigate or a destroyer at the largest.";
125 } else {
126 size = "The vessel is likely to be at least cruiser-sized.";
127 }
128
129 if (size != null) {
130 text1 += "\n\n" + size;
131 text1ForIntel += "\n\n" + size;
132 }
133 }
134 }
135
136 addText(text1);
137
138 BreadcrumbIntelV2 intel = new BreadcrumbIntelV2(target);
139 intel.setTitle(getString(subject));
140 intel.setText(getString(text1ForIntel));
141
142
143 String iconId = null;
144 if (target instanceof CampaignTerrainAPI &&
145 ((CampaignTerrainAPI)target).getPlugin() instanceof DebrisFieldTerrainPlugin) {
146 iconId = "link_to_debris_field";
147 }
148 if (iconId == null) {
149 boolean wreck = SalvorsTallyIntel.isDerelictShip(target);
150 boolean station = SalvorsTallyIntel.isOrbitalInstallation(target);
151 if (target instanceof PlanetAPI) {
152 iconId = "link_to_ruins";
153 } else if (wreck) {
154 iconId = "link_to_derelict_ship";
155 } else if (station) {
156 iconId = "link_to_orbital_installation";
157 } else {
158 iconId = "link_to_other";
159 }
160 }
161
162 if (iconId != null) {
163 //intel.setIcon(Global.getSettings().getSpriteName("intel", iconId));
164 intel.setIconId(iconId);
165 }
166 Global.getSector().getIntelManager().addIntel(intel, false, text);
167
168// CommMessageAPI message = FleetLog.beginEntry(subject, target);
169// message.getSection1().addPara(getString(text1));
170// FleetLog.addToLog(message, text);
171
172 //unsetData();
173 setDone(true);
174 //setShowAgain(true);
175 }
176
177 public static String getNameWithAOrAn(SectorEntityToken target, String override, boolean lowercaseDebris, boolean forTitle) {
178 String targetAOrAn = "a";
179 String targetName = override;
180 if (targetName == null) {
181 if (target instanceof CustomCampaignEntityAPI) {
183 targetName = custom.getCustomEntitySpec().getNameInText();
184 if (forTitle) targetName = custom.getName();
185 targetAOrAn = custom.getCustomEntitySpec().getAOrAn();
186 } else if (target instanceof PlanetAPI) {
187 PlanetAPI planet = (PlanetAPI) target;
188 targetName = planet.getTypeNameWithLowerCaseWorld().toLowerCase();
189 targetName += " with unexplored ruins";
190 if (forTitle) targetName = planet.getTypeNameWithWorld();
191 targetAOrAn = planet.getSpec().getAOrAn();
192 } else {
193 targetName = target.getName();
194 }
195 }
196 if (lowercaseDebris && target.hasTag(Tags.DEBRIS_FIELD)) {
197 targetName = targetName.toLowerCase();
198 }
199 return targetAOrAn + " " + targetName;
200 }
201
202 public static String getLocatedString(SectorEntityToken target) {
203 return getLocatedString(target, false);
204 }
205 public static String getLocatedString(SectorEntityToken target, boolean withSystem) {
206 String loc = getLocationDescription(target, withSystem);
207
208 String orbiting = "";
209 boolean useTerrain = false;
210 if (target.getOrbitFocus() != null) {
211 if (target.getOrbitFocus() instanceof PlanetAPI) {
212 PlanetAPI focus = (PlanetAPI) target.getOrbitFocus();
213 boolean isPrimary = target.getContainingLocation() instanceof StarSystemAPI &&
214 focus == ((StarSystemAPI)target.getContainingLocation()).getStar();
215 if (!focus.isStar() || !isPrimary) {
216 orbiting = "orbiting " + focus.getSpec().getAOrAn() + " " + focus.getTypeNameWithLowerCaseWorld().toLowerCase() + " in ";
217 } else {
218 float dist = Misc.getDistance(focus.getLocation(), target.getLocation());
219 //float dist = Misc.getDistance(new Vector2f(), target.getLocation());
220 if (dist < 3000) {
221 orbiting = "located in the heart of ";
222 } else if (dist > 12000) {
223 orbiting = "located in the outer reaches of ";
224 } else {
225 //orbiting = "located in ";
226 orbiting = "located some distance away from the center of ";
227 }
228 useTerrain = true;
229 }
230 } else if (target.getOrbitFocus() instanceof CustomCampaignEntityAPI) {
232 orbiting = "orbiting " + custom.getCustomEntitySpec().getAOrAn() + " " + custom.getCustomEntitySpec().getNameInText() + " in ";
233 } else if (target.getOrbitFocus() instanceof JumpPointAPI) {
234 orbiting = "orbiting a jump-point in ";
235 } else if (target.getOrbitFocus() instanceof CampaignTerrainAPI) {
237 String n = t.getPlugin().getNameForTooltip().toLowerCase();
238 String a = Misc.getAOrAnFor(n);
239 orbiting = "located inside " + a + " " + n + " ";
240
241 float dist = Misc.getDistance(new Vector2f(), target.getLocation());
242 if (dist < 3000) {
243 orbiting += "in the heart of ";
244 } else if (dist > 12000) {
245 orbiting += "in the outer reaches of ";
246 } else {
247 orbiting += "some distance away from the center of ";
248 }
249 } else { // center of a binary/nebula/etc
250 //float dist = Misc.getDistance(target.getOrbitFocus().getLocation(), target.getLocation());
251 float dist = Misc.getDistance(new Vector2f(), target.getLocation());
252 if (dist < 3000) {
253 orbiting = "located in the heart of ";
254 } else if (dist > 12000) {
255 orbiting = "located in the outer reaches of ";
256 } else {
257 //orbiting = "located in ";
258 orbiting = "located some distance away from the center of ";
259 }
260 useTerrain = true;
261 }
262 } else if (target.getContainingLocation() != null && target.getContainingLocation().isNebula()) {
263 float dist = Misc.getDistance(new Vector2f(), target.getLocation());
264 if (dist < 3000) {
265 orbiting = "located in the heart of ";
266 } else if (dist > 12000) {
267 orbiting = "located on the outskirts of ";
268 } else {
269 //orbiting = "located in ";
270 orbiting = "located some distance away from the center of ";
271 }
272 useTerrain = true;
273 }
274
275 if (useTerrain) {
276 String terrainString = getTerrainString(target);
277 if (terrainString != null) {
278 orbiting = "located in " + terrainString + " in ";
279 }
280 }
281
282 if (orbiting == null || orbiting.isEmpty()) orbiting = "located in ";
283 return orbiting + loc;
284 }
285
287 if (!(entity.getContainingLocation() instanceof StarSystemAPI)) return null;
288
290 for (CampaignTerrainAPI terrain : system.getTerrainCopy()) {
291 if (!terrain.getPlugin().containsEntity(entity)) continue;
292
293 String type = terrain.getType();
294
295 if (Terrain.ASTEROID_BELT.equals(type)) return "an asteroid belt";
296 if (Terrain.ASTEROID_FIELD.equals(type)) return "an asteroid field";
297 //if (Terrain.MAGNETIC_FIELD.equals(type)) return "a magnetic field";
298 if (terrain.hasTag(Tags.ACCRETION_DISK)) return "an accretion disk";
299 if (Terrain.RING.equals(type)) return "a ring system";
300 }
301
302 return null;
303 }
304
305 public static String getLocationDescription(SectorEntityToken entity, boolean withSystem) {
307 if (loc == null) {
308 return "an unknown location";
309 }
310 if (loc.isHyperspace()) {
311 return "hyperspace";
312 }
313 StarSystemAPI system = (StarSystemAPI) loc;
314
315// if (system == Global.getSector().getCurrentLocation()) {
316// return "the " + system.getNameWithLowercaseType();
317// }
318
319 //if (entity.getConstellation() != null && entity.getConstellation() != Global.getSector().getCurrentLocation().getConstellation()) {
320 if (withSystem || entity.getConstellation() == null || entity.getConstellation().getSystems().size() == 1 ||
322 return "the " + system.getNameWithLowercaseType();
323 }
324
326 String cText = "in the " + c.getNameWithLowercaseType();
327 if (c.getSystems().size() == 1) {
328 return "the " + system.getNameWithLowercaseType();
329 }
330
331 if (system.isNebula()) {
332 return "a nebula " + cText;
333 }
334
335 if (system.getTertiary() != null) {
336 return "a trinary star system " + cText;
337 }
338
339 if (system.getSecondary() != null) {
340 return "a binary star system " + cText;
341 }
342
343 PlanetAPI star = system.getStar();
344 if (star != null) {
345 if (star.getSpec().isBlackHole()) {
346 return "a black hole system " + cText;
347 }
348
349 //String sysText = star.getSpec().getAOrAn() + " " + star.getSpec().getName().toLowerCase() + " system ";
350
351 String type = getStarTypeName(star);
352 String color = getStarColorName(star);
353
354 String sysText = null;
356 int cColor = counts.getCount(color);
357 int cType = counts.getCount(type);
358 if (cColor > 1 && cType > cColor) {
359 sysText = "a system with " + star.getSpec().getAOrAn() + " " + color + " primary star ";
360 } else if (cType > 0) {
361 sysText = "a system with " + "a" + " " + type + " primary star ";
362 } else if (cColor > 0) {
363 sysText = "a system with " + star.getSpec().getAOrAn() + " " + color + " primary star ";
364 }
365
366 if (sysText != null) {
367 return sysText + cText;
368 }
369 }
370
371 //if (system.getType() == StarSystemType.SINGLE) {
372 return "the " + system.getNameWithLowercaseType() + " " + cText;
373 //return "orbit around " + getStarDescription(system.getStar()) + " " + cText;
374 }
375
378 for (StarSystemAPI system : c.getSystems()) {
379 PlanetAPI star = system.getStar();
380 if (system.isNebula()) continue;
381 if (system.getSecondary() != null) continue;
382 if (system.getTertiary() != null) continue;
383
384 String type = getStarTypeName(star);
385 String color = getStarColorName(star);
386 if (type != null) map.add(type);
387 if (color != null) map.add(color);
388 }
389 return map;
390 }
391
392 public static String getStarTypeName(PlanetAPI star) {
393 String name = star.getSpec().getName().toLowerCase();
394 if (name.contains(" dwarf")) {
395 return "dwarf";
396 } else if (name.contains(" star")) {
397 return null;
398 } else if (name.contains(" giant")) {
399 return "giant";
400 } else if (name.contains(" supergiant")) {
401 return "supergiant";
402 }
403 return null;
404 }
405 public static String getStarColorName(PlanetAPI star) {
406 String name = star.getSpec().getName().toLowerCase();
407 if (name.contains(" dwarf")) {
408 name = name.replace(" dwarf", "");
409 } else if (name.contains(" star")) {
410 name = name.replace(" star", "");
411 } else if (name.contains(" giant")) {
412 name = name.replace(" giant", "");
413 } else if (name.contains(" supergiant")) {
414 name = name.replace(" supergiant", "");
415 }
416 if (!name.equals(star.getSpec().getName().toLowerCase())) {
417 return name;
418 }
419 return null;
420 }
421
422 /*
423 public static String getStarDescription(PlanetAPI star) {
424 String type = star.getTypeId();
425
426 if (type.equals(StarTypes.BLACK_HOLE)) return "a black hole";
427 if (type.equals(StarTypes.NEUTRON_STAR)) return "a neutron star";
428
429 if (type.equals(StarTypes.ORANGE) ||
430 type.equals(StarTypes.ORANGE_GIANT)) {
431 return "an orange star";
432 }
433
434 if (type.equals(StarTypes.RED_DWARF) ||
435 type.equals(StarTypes.RED_SUPERGIANT) ||
436 type.equals(StarTypes.RED_GIANT)) {
437 return "a red star";
438 }
439
440 if (type.equals(StarTypes.BLUE_GIANT) ||
441 type.equals(StarTypes.BLUE_SUPERGIANT)) {
442 return "a blue star";
443 }
444
445 if (type.equals(StarTypes.BROWN_DWARF) ||
446 type.equals(StarTypes.WHITE_DWARF)) {
447 return "a dim star";
448 }
449
450 if (type.equals(StarTypes.YELLOW)) {
451 return "a yellow star";
452 }
453
454 return "a star of unknown type";
455 }
456 */
457
458 @Override
459 public void optionSelected(String optionText, Object optionData) {
460 super.optionSelected(optionText, optionData);
461 }
462
463
464}
465
466
467
static SectorAPI getSector()
Definition Global.java:65
static String getLocatedString(SectorEntityToken target, boolean withSystem)
static String getLocationDescription(SectorEntityToken entity, boolean withSystem)
static String getNameWithAOrAn(SectorEntityToken target, String override, boolean lowercaseDebris, boolean forTitle)
void add(K key, int quantity)
static MarketConditionSpecAPI getRuinsSpec(MarketAPI market)
Definition Misc.java:5891
static String getAOrAnFor(String word)
Definition Misc.java:6160
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static boolean hasUnexploredRuins(MarketAPI market)
Definition Misc.java:5879
List< CampaignTerrainAPI > getTerrainCopy()
SectorEntityToken getEntityById(String id)
CustomCampaignEntityPlugin getCustomPlugin()