Starsector API
Loading...
Searching...
No Matches
PlanetInteractionDialogPluginImpl.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign;
2
3import java.awt.Color;
4import java.util.HashMap;
5import java.util.Map;
6
7import org.lwjgl.input.Keyboard;
8
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.CargoAPI;
12import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
13import com.fs.starfarer.api.campaign.InteractionDialogAPI;
14import com.fs.starfarer.api.campaign.InteractionDialogPlugin;
15import com.fs.starfarer.api.campaign.OptionPanelAPI;
16import com.fs.starfarer.api.campaign.PlanetAPI;
17import com.fs.starfarer.api.campaign.SpecialItemData;
18import com.fs.starfarer.api.campaign.StarSystemAPI;
19import com.fs.starfarer.api.campaign.TextPanelAPI;
20import com.fs.starfarer.api.campaign.VisualPanelAPI;
21import com.fs.starfarer.api.campaign.rules.MemKeys;
22import com.fs.starfarer.api.campaign.rules.MemoryAPI;
23import com.fs.starfarer.api.combat.EngagementResultAPI;
24import com.fs.starfarer.api.impl.campaign.ids.Commodities;
25import com.fs.starfarer.api.impl.campaign.ids.Items;
26import com.fs.starfarer.api.impl.campaign.ids.Sounds;
27import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTNonASBScanFactor;
28import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTPoints;
29import com.fs.starfarer.api.impl.campaign.intel.events.ht.HyperspaceTopographyEventIntel;
30import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
31import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
32import com.fs.starfarer.api.impl.campaign.rulecmd.DumpMemory;
33import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption;
34import com.fs.starfarer.api.loading.Description;
35import com.fs.starfarer.api.loading.Description.Type;
36import com.fs.starfarer.api.util.Misc;
37
38public class PlanetInteractionDialogPluginImpl implements InteractionDialogPlugin {
39
40 public static int STABLE_FUEL_REQ = 500;
41 public static int STABLE_MACHINERY_REQ = 200;
42
43
44 //public static String BLACK_HOLE_SCANNED = "$blackHoleScanned";
45 public static String ADDED_KEY = "$core_starAddedStable";
46
47 private static enum OptionId {
48 INIT,
49 ADD_STABLE_CONFIRM,
50 ADD_STABLE_DESCRIBE,
51 //SCAN_BlACK_HOLE,
52 DUMP_PLANETKILLER,
53 DUMP_PLANETKILLER_ON_SECOND_THOUGHT,
54 DUMP_PLANETKILLER_CONT_1,
55 ADD_STABLE_NEVER_MIND,
56 LEAVE,
57 }
58
59 private InteractionDialogAPI dialog;
60 private TextPanelAPI textPanel;
61 private OptionPanelAPI options;
62 private VisualPanelAPI visual;
63
64 private CampaignFleetAPI playerFleet;
65 private PlanetAPI planet;
66 private boolean unpauseOnExit = true;
67
68 public boolean isUnpauseOnExit() {
69 return unpauseOnExit;
70 }
71
72 public void setUnpauseOnExit(boolean unpauseOnExit) {
73 this.unpauseOnExit = unpauseOnExit;
74 }
75
76
77 private static final Color HIGHLIGHT_COLOR = Global.getSettings().getColor("buttonShortcut");
78
79 public void init(InteractionDialogAPI dialog) {
80 this.dialog = dialog;
81
82// dialog.hideVisualPanel();
83// dialog.setTextWidth(700);
84
85 textPanel = dialog.getTextPanel();
86 options = dialog.getOptionPanel();
87 visual = dialog.getVisualPanel();
88
89 playerFleet = Global.getSector().getPlayerFleet();
90 planet = (PlanetAPI) dialog.getInteractionTarget();
91
92 visual.setVisualFade(0.25f, 0.25f);
93
94 if (planet.getCustomInteractionDialogImageVisual() != null) {
95 visual.showImageVisual(planet.getCustomInteractionDialogImageVisual());
96 } else {
97 if (!Global.getSettings().getBoolean("3dPlanetBGInInteractionDialog")) {
98 visual.showPlanetInfo(planet);
99 }
100 }
101
102 dialog.setOptionOnEscape("Leave", OptionId.LEAVE);
103
104 optionSelected(null, OptionId.INIT);
105 }
106
107 public Map<String, MemoryAPI> getMemoryMap() {
108 return null;
109 }
110
111 public void backFromEngagement(EngagementResultAPI result) {
112 // no combat here, so this won't get called
113 }
114
115 public void optionSelected(String text, Object optionData) {
116 if (optionData == null) return;
117
118 if (optionData == DumpMemory.OPTION_ID) {
119 Map<String, MemoryAPI> memoryMap = new HashMap<String, MemoryAPI>();
120 MemoryAPI memory = dialog.getInteractionTarget().getMemory();
121
122 memoryMap.put(MemKeys.LOCAL, memory);
123 if (dialog.getInteractionTarget().getFaction() != null) {
124 memoryMap.put(MemKeys.FACTION, dialog.getInteractionTarget().getFaction().getMemory());
125 } else {
126 memoryMap.put(MemKeys.FACTION, Global.getFactory().createMemory());
127 }
128 memoryMap.put(MemKeys.GLOBAL, Global.getSector().getMemory());
129 memoryMap.put(MemKeys.PLAYER, Global.getSector().getCharacterData().getMemory());
130
131 if (dialog.getInteractionTarget().getMarket() != null) {
132 memoryMap.put(MemKeys.MARKET, dialog.getInteractionTarget().getMarket().getMemory());
133 }
134
135 new DumpMemory().execute(null, dialog, null, memoryMap);
136
137 return;
138 } else if (DevMenuOptions.isDevOption(optionData)) {
139 DevMenuOptions.execute(dialog, (String) optionData);
140 return;
141 }
142
143 OptionId option = (OptionId) optionData;
144
145 if (text != null) {
146 //textPanel.addParagraph(text, Global.getSettings().getColor("buttonText"));
147 dialog.addOptionSelectedText(option);
148 }
149
150 String type = "star";
151 String corona = "star's corona";
152 String corona2 = "in the star's corona";
153 if (planet.getSpec().isBlackHole()) {
154 type = "black hole";
155 corona = "event horizon";
156 corona2 = "near the event horizon";
157 }
158
159 switch (option) {
160 case INIT:
161 //boolean scannedAlready = planet.getMemoryWithoutUpdate().getBoolean(BLACK_HOLE_SCANNED);
162 boolean didAlready = planet.getMemoryWithoutUpdate().getBoolean(ADDED_KEY);
163 addText(getString("approach"));
164
165 if (planet.getMemoryWithoutUpdate().getBoolean("$abyssalBlackHoleReadings")) {
166 planet.getMemoryWithoutUpdate().unset("$abyssalBlackHoleReadings");
167 planet.getMemoryWithoutUpdate().set("$abyssalBlackHoleReadingsRevisit", true);
168
169 addText("Your sensors officer hesitates, then calls for your attention. \"Captain, there's a... pattern. "
170 + "From the black hole. Or, rather,\" they pause, looking almost embarrassed. \"-The energy radiated"
171 + " by the accretion disc."
172 + "\n\n"
173 + "They pull a collated sensor output map into the primary holo. \"It's almost a signal. See, if we "
174 + "chart these fluctuations in energy output over time..."
175 + "\n\n"
176 + "You see it now, an orderly series. Not quite a sequence of prime numbers, "
177 + "unless you jig the math. Statistically this is nearly impossible. Possible explanations "
178 + "are as unlikely: a series of planets - large moons? - with specific mass-ratio relationships, "
179 + "all pulled into the accretion disc at just such an angle, like an intentional "
180 + "message... or orderly annihilation of a constructed planetary system at a scale beyond the wildest "
181 + "dreams of the most bloody-minded war-planners of the Domain."
182 + "\n\n"
183 + "It can't be known. The pattern disappears as quickly as it arose.");
184
185 int points = HTPoints.ABYSSAL_BLACK_HOLE_UNUSUAL_READINGS;
186 if (points > 0) {
187 HyperspaceTopographyEventIntel.addFactorCreateIfNecessary(
188 new HTNonASBScanFactor("Picked up unusual readings from abyssal black hole", points), dialog);
189 }
190 } else if (planet.getMemoryWithoutUpdate().getBoolean("$abyssalBlackHoleReadingsRevisit")) {
191 addText("Your sensors officer detects no more unusual energy patterns from the inner rim of the accretion disc, just noise,"
192 + " as mindless as the background radiation of the cosmos itself.");
193 }
194
195 if (didAlready) {
196 addText("The " + corona + " exhibits fluctuations indicative of recent antimatter application.");
197 }
198// if (scannedAlready) {
199// addText("You've scanned this black hole.");
200// }
201
202 Description desc = Global.getSettings().getDescription(planet.getCustomDescriptionId(), Type.CUSTOM);
203 if (desc != null && desc.hasText3()) {
204 addText(desc.getText3());
205 }
207 break;
208 case DUMP_PLANETKILLER:
209 addText("Your officers respond promptly to the order, and move to the task with all alacrity. There is an edge to their call-and-response,"
210 + " however, as if they cannot help but acknowledge the deep sense of the gravity in this act.\n"
211 + "\"Package ready to drop, captain,\" your ops chief says. \"On your order.\"");
212 options.clearOptions();
213 options.addOption("\"Destroy it!\"", OptionId.DUMP_PLANETKILLER_CONT_1, null);
214 options.addOption("\"No... I will keep it.\"", OptionId.DUMP_PLANETKILLER_ON_SECOND_THOUGHT, null); // Isildur, nooo!!!
215 break;
216 case DUMP_PLANETKILLER_ON_SECOND_THOUGHT:
218 break;
219 case DUMP_PLANETKILLER_CONT_1:
220 addText("At your command the planetkiller, locked in its cradle, is boosted toward the very center of the black hole, up and over the plane of the accretion disc.\n\n"
221 + "With a flash only a little more than noise in the sensor telemetry, it is gone."); //, like tears in rain"); - OMG Alex, you're killing me -dgb
222 AddRemoveCommodity.addItemLossText(new SpecialItemData(Items.PLANETKILLER, null), 1, dialog.getTextPanel());
223 Global.getSector().getPlayerStats().addStoryPoints(1, dialog.getTextPanel(), false);
224 removePK();
225 options.clearOptions();
226 options.addOption("Leave", OptionId.LEAVE, null);
227 options.setShortcut(OptionId.LEAVE, Keyboard.KEY_ESCAPE, false, false, false, true);
228 break;
229// case SCAN_BlACK_HOLE:
230// planet.getMemoryWithoutUpdate().set(BLACK_HOLE_SCANNED, true);
231// addText("TODO TODO TODO Your sensors officer works quickly, initiating a multi-wave scan of the black hole - or, rather, its event horizon. "
232// + "A few minutes later, you have the data; "
233// + "not terribly useful on its own, but gradually reaching a critical mass "
234// + "when combined with other readings taken elsewhere.");
235// HyperspaceTopographyEventIntel.addFactorCreateIfNecessary(new HTBlackHoleFactor(), dialog);
236// createInitialOptions();
237// break;
238 case ADD_STABLE_CONFIRM:
239 StarSystemAPI system = planet.getStarSystem();
240 if (system != null) {
241
242 CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo();
243 cargo.removeFuel(STABLE_FUEL_REQ);
244 AddRemoveCommodity.addCommodityLossText(Commodities.FUEL, STABLE_FUEL_REQ, dialog.getTextPanel());
245 StarSystemGenerator.addStableLocations(system, 1);
246 planet.getMemoryWithoutUpdate().set(ADDED_KEY, true);
247 addText("Preparations are made, and you give the go-ahead. " +
248 "A few tense minutes later, the chief engineer reports success. " +
249 "The resulting stable location won't last for millennia, like " +
250 "naturally-occurring ones - but it'll do for your purposes.");
251 }
253 break;
254 case ADD_STABLE_DESCRIBE:
255 addText("The procedure requires spreading prodigious amounts of antimatter " + corona2 + ", " +
256 "according to calculations far beyond the ability of anything on the right side of the " +
257 "treaty that ended the Second AI War.");
258 boolean canAfford = dialog.getTextPanel().addCostPanel("Resources required (available)",
259 Commodities.ALPHA_CORE, 1, false,
260 Commodities.HEAVY_MACHINERY, STABLE_MACHINERY_REQ, false,
261 Commodities.FUEL, STABLE_FUEL_REQ, true
262 );
263
264 options.clearOptions();
265
266 int num = Misc.getNumStableLocations(planet.getStarSystem());
267 boolean alreadyCant = false;
268 if (num <= 0) {
269 options.addOption("Proceed with the operation", OptionId.ADD_STABLE_CONFIRM, null);
270 } else if (num < 2) {
271 addText("Normally, this procedure can only be performed in a star system without any " +
272 "stable locations. However, your chief engineer suggests an unorthodox workaround.");
273 options.addOption("Proceed with the operation", OptionId.ADD_STABLE_CONFIRM, null);
274 SetStoryOption.set(dialog, Global.getSettings().getInt("createStableLocation"),
275 OptionId.ADD_STABLE_CONFIRM, "createStableLocation", Sounds.STORY_POINT_SPEND_TECHNOLOGY,
276 "Created additional stable location in " + planet.getStarSystem().getNameWithLowercaseType() + "");
277 } else {
278 alreadyCant = true;
279
280 String reason = "This procedure can not performed in a star system that already has " +
281 "numerous stable locations.";
282 options.addOption("Proceed with the operation", OptionId.ADD_STABLE_CONFIRM, null);
283 options.setEnabled(OptionId.ADD_STABLE_CONFIRM, false);
284 addText(reason);
285 options.setTooltip(OptionId.ADD_STABLE_CONFIRM, reason);
286 }
287
288 if (!canAfford && !alreadyCant) {
289 String reason = "You do not have the necessary resources to carry out this procedure.";
290 options.setEnabled(OptionId.ADD_STABLE_CONFIRM, false);
291 addText(reason);
292 options.setTooltip(OptionId.ADD_STABLE_CONFIRM, reason);
293 }
294
295
296 options.addOption("Never mind", OptionId.ADD_STABLE_NEVER_MIND, null);
297 //createInitialOptions();
298 break;
299 case ADD_STABLE_NEVER_MIND:
301 break;
302 case LEAVE:
303 if (unpauseOnExit) {
304 Global.getSector().setPaused(false);
305 }
306 dialog.dismiss();
307 break;
308 }
309 }
310
311
312 protected void createInitialOptions() {
313 options.clearOptions();
314
315 MemoryAPI memory = dialog.getInteractionTarget().getMemory();
316
317 String type = "star";
318 String corona = "star's corona";
319 String corona2 = "in the star's corona";
320 boolean blackHole = false;
321 if (planet.getSpec().isBlackHole()) {
322 blackHole = true;
323 type = "black hole";
324 corona = "event horizon";
325 corona2 = "near the event horizon";
326 }
327
328 StarSystemAPI system = planet.getStarSystem();
329 //boolean scannedAlready = planet.getMemoryWithoutUpdate().getBoolean(BLACK_HOLE_SCANNED);
330 boolean didAlready = planet.getMemoryWithoutUpdate().getBoolean(ADDED_KEY);
331 boolean deepSpace = system.isDeepSpace();
332 if (system != null && planet == system.getStar() && !didAlready && !deepSpace) {
333// int num = Misc.getNumStableLocations(planet.getStarSystem());
334 //options.addOption("Induce a resonance cascade in the star's hyperfield, creating a stable location", OptionId.ADD_STABLE_DESCRIBE, null);
335 options.addOption("Consider inducing a resonance cascade in the " + type + "'s hyperfield, creating a stable location", OptionId.ADD_STABLE_DESCRIBE, null);
336// SetStoryOption.set(dialog, Global.getSettings().getInt("createStableLocation"),
337// OptionId.ADD_STABLE, "createStableLocation", Sounds.STORY_POINT_SPEND_TECHNOLOGY);
338// if (num >= 3) {
339// options.setEnabled(OptionId.ADD_STABLE, false);
340// options.setTooltip(OptionId.ADD_STABLE, "This star system can't have any more stable locations.");
341// }
342// if (num >= 0) {
343// options.setEnabled(OptionId.ADD_STABLE, false);
344// options.setTooltip(OptionId.ADD_STABLE, "This procedure can only be performed in star systems " +
345// "without any stable locations.");
346// }
347 }
348
349// if (blackHole && !scannedAlready) {
350// options.addOption("Scan the black hole to assess its impact on local hyperspace topography",
351// OptionId.SCAN_BlACK_HOLE, null);
352// }
353
354
355 if (hasPK() && blackHole == true) {
356 options.addOption("Dump the planetkiller weapon into the black hole", OptionId.DUMP_PLANETKILLER, null);
357 }
358
359 options.addOption("Leave", OptionId.LEAVE, null);
360 options.setShortcut(OptionId.LEAVE, Keyboard.KEY_ESCAPE, false, false, false, true);
361
362 if (Global.getSettings().isDevMode()) {
364 }
365 }
366
367 public void removePK() {
368 Global.getSector().getPlayerFleet().getCargo().
369 removeItems(CargoItemType.SPECIAL, new SpecialItemData(Items.PLANETKILLER, null), 1);
370 }
371 public boolean hasPK() {
372 return Global.getSector().getPlayerFleet().getCargo().
373 getQuantity(CargoItemType.SPECIAL, new SpecialItemData(Items.PLANETKILLER, null)) > 0;
374 }
375
376
377 private OptionId lastOptionMousedOver = null;
378 public void optionMousedOver(String optionText, Object optionData) {
379
380 }
381
382 public void advance(float amount) {
383
384 }
385
386 private void addText(String text) {
387 textPanel.addParagraph(text);
388 }
389
390 private void appendText(String text) {
391 textPanel.appendToLastParagraph(" " + text);
392 }
393
394 private String getString(String id) {
395 String str = Global.getSettings().getString("planetInteractionDialog", id);
396
397 String fleetOrShip = "fleet";
398 if (playerFleet.getFleetData().getMembersListCopy().size() == 1) {
399 fleetOrShip = "ship";
400 if (playerFleet.getFleetData().getMembersListCopy().get(0).isFighterWing()) {
401 fleetOrShip = "fighter wing";
402 }
403 }
404 str = str.replaceAll("\\$fleetOrShip", fleetOrShip);
405 str = str.replaceAll("\\$planetName", planet.getName());
406
407 return str;
408 }
409
410
411 public Object getContext() {
412 return null;
413 }
414}
415
416
417
static SettingsAPI getSettings()
Definition Global.java:51
static FactoryAPI getFactory()
Definition Global.java:35
static SectorAPI getSector()
Definition Global.java:59
static void execute(InteractionDialogAPI dialog, String option)
static boolean isDevOption(Object optionData)
static void addOptions(InteractionDialogAPI dialog)
Description getDescription(String id, Type type)
String getString(String category, String id)
boolean getBoolean(String key)