Starsector API
Loading...
Searching...
No Matches
BarCMD.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.rulecmd.missions;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.List;
7import java.util.Map;
8import java.util.Random;
9
10import org.lwjgl.input.Keyboard;
11
12import com.fs.starfarer.api.EveryFrameScript;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.InteractionDialogAPI;
15import com.fs.starfarer.api.campaign.InteractionDialogPlugin;
16import com.fs.starfarer.api.campaign.SectorEntityToken;
17import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
18import com.fs.starfarer.api.campaign.econ.MarketAPI;
19import com.fs.starfarer.api.campaign.rules.MemKeys;
20import com.fs.starfarer.api.campaign.rules.MemoryAPI;
21import com.fs.starfarer.api.characters.ImportantPeopleAPI;
22import com.fs.starfarer.api.characters.PersonAPI;
23import com.fs.starfarer.api.combat.EngagementResultAPI;
24import com.fs.starfarer.api.impl.campaign.DebugFlags;
25import com.fs.starfarer.api.impl.campaign.DevMenuOptions;
26import com.fs.starfarer.api.impl.campaign.RuleBasedInteractionDialogPluginImpl;
27import com.fs.starfarer.api.impl.campaign.intel.bar.BarEventDialogPlugin;
28import com.fs.starfarer.api.impl.campaign.intel.bar.PortsideBarData;
29import com.fs.starfarer.api.impl.campaign.intel.bar.PortsideBarEvent;
30import com.fs.starfarer.api.impl.campaign.intel.bar.events.BarEventManager;
31import com.fs.starfarer.api.impl.campaign.intel.contacts.ContactIntel;
32import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionBarEventWrapper;
33import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin;
34import com.fs.starfarer.api.impl.campaign.rulecmd.DumpMemory;
35import com.fs.starfarer.api.impl.campaign.rulecmd.FireAll;
36import com.fs.starfarer.api.impl.campaign.rulecmd.FireBest;
37import com.fs.starfarer.api.impl.campaign.rulecmd.ShowDefaultVisual;
38import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.AddBarEvent;
39import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.AddBarEvent.BarEventData;
40import com.fs.starfarer.api.impl.campaign.tutorial.TutorialMissionIntel;
41import com.fs.starfarer.api.util.FaderUtil;
42import com.fs.starfarer.api.util.Misc;
43import com.fs.starfarer.api.util.Misc.Token;
44import com.fs.starfarer.api.util.WeightedRandomPicker;
45
49public class BarCMD extends BaseCommandPlugin implements InteractionDialogPlugin {
50
51 public static float BAR_EVENT_MIN_TIME_BEFORE_CHANGING = 20f;
52 public static float BAR_EVENT_MAX_TIME_BEFORE_CHANGING = 40f;
53
54 protected SectorEntityToken entity;
55 protected InteractionDialogPlugin originalPlugin;
56 protected InteractionDialogAPI dialog;
57 protected Map<String, MemoryAPI> memoryMap;
58
59 public static class BarAmbiencePlayer implements EveryFrameScript {
60 public MarketAPI market;
61 public String soundId = "bar_ambience";
62 public float pitch = 1f;
63 public float volume = 1f;
64 public float musicSuppression = 0.95f;
65 public boolean done = false;
66
67 public FaderUtil fader = new FaderUtil(0f, 0.5f);
68 public BarAmbiencePlayer(MarketAPI market) {
69 this.market = market;
70 if (market.getFaction() != null) {
71 soundId = market.getFaction().getBarSound();
72 }
73 fader.fadeIn();
74 }
75 public void advance(float amount) {
76 fader.advance(amount);
77 Global.getSector().getCampaignUI().suppressMusic(fader.getBrightness() * musicSuppression);
78 Global.getSoundPlayer().playUILoop(soundId, pitch, volume * fader.getBrightness());
79 if (!Global.getSector().isPaused()) {
80 stop();
81 }
82 }
83 public boolean isDone() {
84 return done;
85 }
86 public boolean runWhilePaused() {
87 return true;
88 }
89 public void stop() {
90 done = true;
91 }
92 }
93
94 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, final Map<String, MemoryAPI> memoryMap) {
95 this.dialog = dialog;
96 this.memoryMap = memoryMap;
97 if (dialog == null) return false;
98
99 String command = params.get(0).getString(memoryMap);
100 if (command == null) return false;
101
102
103 if (command.equals("returnFromEvent")) {
104 MemoryAPI mem = getEntityMemory(memoryMap);
105 BarCMD cmd = (BarCMD) mem.get("$BarCMD");
106 mem.unset("$BarCMD");
107 //mem.unset("$currMission_ref");
108
109 dialog.setPlugin(cmd);
110 abortMissions(null);
111
112 dialog.getInteractionTarget().setActivePerson(null);
114// memoryMap.put(MemKeys.LOCAL, dialog.getInteractionTarget().getMemoryWithoutUpdate());
115// memoryMap.remove(MemKeys.ENTITY);
116
117
118 boolean withContinue = params.size() > 1 && params.get(1).getBoolean(memoryMap);
119 cmd.returningFromEvent(withContinue);
120
121 return true;
122 } else if (command.equals("accept")) {
123 //MemoryAPI mem = getEntityMemory(memoryMap);
124 //Object ref = mem.get("$currMission_ref");
125
126 String missionId = params.get(1).getString(memoryMap);
127 HubMissionBarEventWrapper w = getWrapperFor(missionId);
128 if (w != null && w.getMission() != null) {
129 BarEventManager.getInstance().notifyWasInteractedWith(w);
130 w.getMission().accept(dialog, memoryMap);
131 }
132 return true;
133 } else if (command.equals("leaveBar")) {
134 leaveBar();
135 return true;
136 } else if (command.equals("playAmbience")) {
137 entity = dialog.getInteractionTarget();
138 if (!Global.getSector().hasTransientScript(BarAmbiencePlayer.class)) {
139 Global.getSector().addTransientScript(new BarAmbiencePlayer(entity.getMarket()));
140 }
141 return true;
142 }
143
144// else if (command.equals("addContact")) {
145// ContactIntel.addPotentialContact(contact, text)
146// }
147
148 entity = dialog.getInteractionTarget();
149 originalPlugin = dialog.getPlugin();
150
151 //FireBest.fire(null, dialog, memoryMap, "SalvageSpecialFinishedNoContinue");
152
153 if (command.equals("showOptions")) {
154 showOptions(false);
155 if (!Global.getSector().hasTransientScript(BarAmbiencePlayer.class)) {
156 Global.getSector().addTransientScript(new BarAmbiencePlayer(entity.getMarket()));
157 }
158 }
159
160 return true;
161 }
162
163 public void showOptions(boolean returningFromEvent) {
164 dialog.getVisualPanel().restoreSavedVisual();
165 dialog.getVisualPanel().saveCurrentVisual();
166
167 PortsideBarData data = PortsideBarData.getInstance();
168
169 MarketAPI market = entity.getMarket();
170
171 dialog.getOptionPanel().clearOptions();
172
173 Random random = new Random(BarEventManager.getInstance().getSeed(entity, null, null));
174
175 int min = Global.getSettings().getInt("minBarEvents");
176 int max = Global.getSettings().getInt("maxBarEvents");
177 float pMult = Global.getSettings().getFloat("barEventProbOneMore");
178 //int num = min + random.nextInt(max - min + 1);
179
180 WeightedRandomPicker<Integer> numPicker = new WeightedRandomPicker<Integer>(random);
181 float p = 1f;
182 for (int i = min; i <= max; i++) {
183 numPicker.add(i, p);
184 p *= pMult;
185 }
186 int num = numPicker.pick();
187
188 if (DebugFlags.BAR_DEBUG) {
189 max = 8;
190 num = 7;
191 //num = max;
192 }
193
194 //num = 1000;
195
196 List<PortsideBarEvent> events = new ArrayList<PortsideBarEvent>();
197 String key = "$BarCMD_shownEvents";
198 MemoryAPI mem = market.getMemoryWithoutUpdate();
199 boolean needToSaveShown = false;
200 if (mem.contains(key)) {
201 List<String> eventIds = (List<String>) mem.get(key);
202 for (String id : eventIds) {
203 OUTER: for (PortsideBarEvent event : data.getEvents()) {
204// for (GenericBarEventCreator c : BarEventManager.getInstance().getTimeout().getItems()) {
205// if (c.getBarEventId() != null && c.getBarEventId().equals(id)) {
206// continue OUTER;
207// }
208// }
209 if (id.equals(event.getBarEventId())) {
210 events.add(event);
211 }
212 }
213 }
214 num = Math.max(eventIds.size(), num);
215 } else {
216 events.addAll(data.getEvents());
217 Collections.shuffle(events, random);
218 needToSaveShown = true;
219 }
220
221 boolean addedSomething = false;
222
223 AddBarEvent.clearTempEvents(market);
224 FireAll.fire(null, dialog, memoryMap, "AddBarEvents");
225
226 List<BarEventData> temp = new ArrayList<BarEventData>(AddBarEvent.getTempEvents(market).events.values());
227 for (int i = 0; i < max && i < temp.size(); i++) {
228 BarEventData b = temp.get(i);
229 if (!b.blurb.isEmpty()) {
230 dialog.getTextPanel().addPara(b.blurb);
231 }
232 dialog.getOptionPanel().addOption(b.option, b.optionId);
233 if (b.optionColor != null) {
234 dialog.setOptionColor(b.optionId, b.optionColor);
235 }
236 addedSomething = true;
237 }
238
239 List<String> shown = new ArrayList<String>();
240
241 // used alongside with ip.excludeFromGetPerson() to ensure that the same person isn't picked
242 // for multiple concurrent bar events
243 ImportantPeopleAPI ip = Global.getSector().getImportantPeople();
244 ip.resetExcludeFromGetPerson();
245
246 // existing contacts don't show up at the bar, since the bar encounter dialogue is written
247 // assuming you're meeting them for the first time
248 for (IntelInfoPlugin intel : Global.getSector().getIntelManager().getIntel(ContactIntel.class)) {
249 ip.excludeFromGetPerson(((ContactIntel)intel).getPerson());
250 }
251
252// BaseMissionHub.resetMissionAngle(null, market);
253// BaseMissionHub.getMissionAngle(null, market, random);
254
255 Collections.sort(events, new Comparator<PortsideBarEvent>() {
256 public int compare(PortsideBarEvent o1, PortsideBarEvent o2) {
257 boolean p1 = o1.isAlwaysShow();
258 boolean p2 = o2.isAlwaysShow();
259 if (p1 && !p2) return -1;
260 if (p2 && !p1) return 1;
261 return 0;
262 }
263 });
264
265 int curr = 0;
266 //for (PortsideBarEvent event : data.getEvents()) {
267 for (PortsideBarEvent event : events) {
268 if (TutorialMissionIntel.isTutorialInProgress()) continue;
269 if (curr + temp.size() >= max) break;
270
271// if (curr < 16) {
272// curr++;
273// continue;
274// }
275
276 if (event.shouldRemoveEvent()) continue;
277 if (!event.shouldShowAtMarket(market)) continue;
278
279 event.addPromptAndOption(dialog, memoryMap);
280 if (event instanceof HubMissionBarEventWrapper) {
281 HubMissionBarEventWrapper w = (HubMissionBarEventWrapper) event;
282 if (w.getMission() == null) { // aborted during creation
283 continue;
284 }
285 }
286 event.wasShownAtMarket(market);
287
288 if (event.getBarEventId() != null) {
289 shown.add(event.getBarEventId());
290 }
291
292 addedSomething = true;
293
294 if (!event.isAlwaysShow()) {
295 curr++;
296 }
297 if (curr >= num) break;
298 }
299
300 //BaseMissionHub.clearCreatedMissionsList(null, market);
301 ip.resetExcludeFromGetPerson();
302
303 if (needToSaveShown) {
306 mem.set(key, shown, time);
307 }
308
309 if (returningFromEvent) {
310 if (!addedSomething) {
311 dialog.getTextPanel().addPara("Nothing of note is going on at the bar.");
312 } else {
313 dialog.getTextPanel().addPara("You unobtrusively watch the patrons of the bar for " +
314 "a few minutes before deciding what to do next.");
315 }
316 }
317
318 dialog.getOptionPanel().addOption("Leave the bar", "barLeave");
319 dialog.getOptionPanel().setShortcut("barLeave", Keyboard.KEY_ESCAPE, false, false, false, true);
320
321
322 if (Global.getSettings().isDevMode()) {
324 }
325
326 dialog.setPlugin(this);
327 init(dialog);
328 }
329
330 public void optionSelected(String optionText, Object optionData) {
331 if (optionText != null) {
332 //dialog.getTextPanel().addParagraph(optionText, Global.getSettings().getColor("buttonText"));
333 dialog.addOptionSelectedText(optionData);
334 }
335 if (optionData == DumpMemory.OPTION_ID) {
336 new DumpMemory().execute(null, dialog, null, getMemoryMap());
337 return;
338 } else if (DevMenuOptions.isDevOption(optionData)) {
339 DevMenuOptions.execute(dialog, (String) optionData);
340 return;
341 }
342
343 // need to abort any HubMissionBarEventWrapper missions that are *not* the current selection
344 String optionId = null;
345 if (optionData instanceof String) {
346 optionId = (String) optionData;
347 }
348
349 abortMissions(optionId);
350
351 if (optionData instanceof PortsideBarEvent) {
352 PortsideBarEvent event = (PortsideBarEvent) optionData;
353 BarEventDialogPlugin plugin = new BarEventDialogPlugin(this, this, event, memoryMap);
354 dialog.setPlugin(plugin);
355 plugin.init(dialog);
356 return;
357 } else if ("barLeave".equals(optionData)) {
358 leaveBar();
359 } else if ("barContinue".equals(optionData)) {
360 showOptions(true);
361 } else if (optionData instanceof String) {
362 // a HubMissionBarEventWrapper option
363// HubMissionBarEventWrapper w = getWrapperFor(optionId);
364// if (w != null && w.getMission() != null) {
365// mem.set("$currMission_ref", w.getMission(), 0f);
366// } else {
367// mem.unset("$currMission_ref");
368// }
369
370 MemoryAPI eMem = getEntityMemory(memoryMap);
371 eMem.set("$BarCMD", this, 0f);
372
373 HubMissionBarEventWrapper w = getWrapperFor(optionId);
374 if (w != null && w.getMission() != null) {
375 PersonAPI person = w.getMission().getPerson();
376 if (person != null) {
377 dialog.getInteractionTarget().setActivePerson(person);
379// memoryMap.put(MemKeys.ENTITY, memoryMap.get(MemKeys.LOCAL));
380// memoryMap.put(MemKeys.LOCAL, person.getMemoryWithoutUpdate());
381 dialog.getVisualPanel().showPersonInfo(person, true);
382 }
383 }
384
385 MemoryAPI mem = memoryMap.get(MemKeys.LOCAL);
386 dialog.setPlugin(originalPlugin);
387 mem.set("$option", (String) optionData, 0f);
388
389 FireBest.fire(null, dialog, memoryMap, "DialogOptionSelected");
390 }
391 }
392
393 public void returningFromEvent(PortsideBarEvent event) {
394 returningFromEvent(event.endWithContinue());
395 }
396 public void returningFromEvent(boolean withContinue) {
397 if (withContinue) {
398 dialog.getOptionPanel().clearOptions();
399 dialog.getOptionPanel().addOption("Continue", "barContinue");
400 } else {
401 showOptions(true);
402 }
403 }
404
405 public HubMissionBarEventWrapper getWrapperFor(String optionId) {
406 PortsideBarData data = PortsideBarData.getInstance();
407 for (PortsideBarEvent event : data.getEvents()) {
408 if (event instanceof HubMissionBarEventWrapper) {
409 HubMissionBarEventWrapper w = (HubMissionBarEventWrapper) event;
410 if (w.getMission() == null) continue;
411 if (optionId != null && optionId.startsWith(w.getMission().getTriggerPrefix())) {
412 return w;
413 }
414 }
415 }
416 return null;
417 }
418 public void abortMissions(String optionId) {
419 PortsideBarData data = PortsideBarData.getInstance();
420 for (PortsideBarEvent event : data.getEvents()) {
421 if (event instanceof HubMissionBarEventWrapper) {
422 HubMissionBarEventWrapper w = (HubMissionBarEventWrapper) event;
423 if (w.getMission() == null) continue;
424 if (optionId == null || !optionId.startsWith(w.getMission().getTriggerPrefix())) {
425 w.abortMission();
426 }
427 }
428 }
429 }
430
431
432 public static BarAmbiencePlayer getAmbiencePlayer() {
433 for (EveryFrameScript script : Global.getSector().getTransientScripts()) {
434 if (script instanceof BarAmbiencePlayer) {
435 return (BarAmbiencePlayer) script;
436 }
437 }
438 return null;
439 }
440
441 public void leaveBar() {
442
443 BarAmbiencePlayer player = getAmbiencePlayer();
444 if (player != null) {
445 player.stop();
446 }
447
448 if (originalPlugin != null) {
449 dialog.setPlugin(originalPlugin);
450 }
451
452 new ShowDefaultVisual().execute(null, dialog, Misc.tokenize(""), memoryMap);
453 FireBest.fire(null, dialog, memoryMap, "ReturnFromBar");
454 }
455
456 public void advance(float amount) {
457 }
458 public void backFromEngagement(EngagementResultAPI battleResult) {
459 }
460 public Object getContext() {
461 return null;
462 }
463 public Map<String, MemoryAPI> getMemoryMap() {
464 return memoryMap;
465 }
466 public void optionMousedOver(String optionText, Object optionData) {
467 }
468
469 public void init(InteractionDialogAPI dialog) {
470 }
471
472}
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
static SettingsAPI getSettings()
Definition Global.java:51
static SoundPlayerAPI getSoundPlayer()
Definition Global.java:43
static SectorAPI getSector()
Definition Global.java:59
static void execute(InteractionDialogAPI dialog, String option)
static boolean isDevOption(Object optionData)
static void addOptions(InteractionDialogAPI dialog)
static MemoryAPI getEntityMemory(Map< String, MemoryAPI > memoryMap)
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
static boolean fire(String ruleId, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap, String params)
Definition FireAll.java:55
static boolean fire(String ruleId, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap, String params)
Definition FireBest.java:56
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
void optionSelected(String optionText, Object optionData)
Definition BarCMD.java:330
void backFromEngagement(EngagementResultAPI battleResult)
Definition BarCMD.java:458
HubMissionBarEventWrapper getWrapperFor(String optionId)
Definition BarCMD.java:405
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, final Map< String, MemoryAPI > memoryMap)
Definition BarCMD.java:94
void optionMousedOver(String optionText, Object optionData)
Definition BarCMD.java:466
void playUILoop(String id, float pitch, float volume)