Starsector API
Loading...
Searching...
No Matches
PerseanLeagueMembership.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel;
2
3import java.awt.Color;
4import java.util.Set;
5
6import org.lwjgl.input.Keyboard;
7
8import com.fs.starfarer.api.Global;
9import com.fs.starfarer.api.campaign.FactionAPI;
10import com.fs.starfarer.api.campaign.InteractionDialogAPI;
11import com.fs.starfarer.api.campaign.RepLevel;
12import com.fs.starfarer.api.campaign.SectorEntityToken;
13import com.fs.starfarer.api.campaign.TextPanelAPI;
14import com.fs.starfarer.api.campaign.econ.MarketAPI;
15import com.fs.starfarer.api.campaign.econ.MonthlyReport;
16import com.fs.starfarer.api.campaign.econ.MonthlyReport.FDNode;
17import com.fs.starfarer.api.campaign.listeners.CommissionEndedListener;
18import com.fs.starfarer.api.campaign.listeners.EconomyTickListener;
19import com.fs.starfarer.api.characters.PersonAPI;
20import com.fs.starfarer.api.impl.campaign.ids.Factions;
21import com.fs.starfarer.api.impl.campaign.ids.People;
22import com.fs.starfarer.api.impl.campaign.ids.Tags;
23import com.fs.starfarer.api.impl.campaign.intel.contacts.ContactIntel;
24import com.fs.starfarer.api.impl.campaign.rulecmd.HA_CMD;
25import com.fs.starfarer.api.impl.campaign.shared.SharedData;
26import com.fs.starfarer.api.ui.ButtonAPI;
27import com.fs.starfarer.api.ui.IntelUIAPI;
28import com.fs.starfarer.api.ui.LabelAPI;
29import com.fs.starfarer.api.ui.SectorMapAPI;
30import com.fs.starfarer.api.ui.TooltipMakerAPI;
31import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
32import com.fs.starfarer.api.util.Misc;
33
34public class PerseanLeagueMembership extends BaseIntelPlugin implements EconomyTickListener, CommissionEndedListener {
35
36 public static enum AgreementEndingType {
37 EXPIRED,
38 BROKEN,
39 ENDED,
40 }
41
42 public static int TIMES_LEFT_LEAGUE_FOR_NO_REJOIN = 2;
43
44 // in $player memory
45 public static final String PL_MEMBERSHIP_GOOD_DEAL = "$hasGoodPLMembershipDeal";
46 public static final String PAYING_HOUSE_HANNAN = "$payingHouseHannan";
47 public static final String LEFT_LEAGUE_WHEN_GOOD_DEAL = "$leftLeagueWhenGoodDeal";
48 public static final String IS_LEAGUE_MEMBER = "$isLeagueMember";
49 public static final String NUM_TIMES_LEFT_LEAGUE = "$numTimesLeftLeague";
50
51 public static final String DEFEATED_BLOCKADE = "$defeatedLeagueBlockade";
52 public static final String DEFEATED_PUN_EX = "$defeatedLeaguePunEx";
53
54 public static int getNumTimesLeftLeague() {
55 return Global.getSector().getPlayerMemoryWithoutUpdate().getInt(NUM_TIMES_LEFT_LEAGUE);
56 }
57 public static void incrLeftLeagueCount() {
58 int count = getNumTimesLeftLeague();
59 Global.getSector().getPlayerMemoryWithoutUpdate().set(NUM_TIMES_LEFT_LEAGUE, count + 1);
60 }
61
62 public static boolean isDefeatedBlockadeOrPunEx() {
63 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(DEFEATED_BLOCKADE) ||
64 Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(DEFEATED_PUN_EX);
65 }
66 public static void setDefeatedBlockade(boolean value) {
67 Global.getSector().getPlayerMemoryWithoutUpdate().set(DEFEATED_BLOCKADE, value);
68 if (!value) {
69 Global.getSector().getPlayerMemoryWithoutUpdate().unset(DEFEATED_BLOCKADE);
70 }
71 }
72 public static void setDefeatedPunEx(boolean value) {
73 Global.getSector().getPlayerMemoryWithoutUpdate().set(DEFEATED_PUN_EX, value);
74 if (!value) {
75 Global.getSector().getPlayerMemoryWithoutUpdate().unset(DEFEATED_PUN_EX);
76 }
77 }
78 public static boolean isGoodDeal() {
79 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(PL_MEMBERSHIP_GOOD_DEAL);
80 }
81
82 public static boolean isPayingHouseHannan() {
83 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(PAYING_HOUSE_HANNAN);
84 }
85 public static void setPayingHouseHannan(boolean value) {
86 Global.getSector().getPlayerMemoryWithoutUpdate().set(PAYING_HOUSE_HANNAN, value);
87 if (!value) {
88 Global.getSector().getPlayerMemoryWithoutUpdate().unset(PAYING_HOUSE_HANNAN);
89 }
90 }
91 public static boolean isLeftLeagueWhenGoodDeal() {
92 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(LEFT_LEAGUE_WHEN_GOOD_DEAL);
93 }
94 public static void setLeftLeagueWhenGoodDeal(boolean value) {
95 Global.getSector().getPlayerMemoryWithoutUpdate().set(LEFT_LEAGUE_WHEN_GOOD_DEAL, value);
96 if (!value) {
97 Global.getSector().getPlayerMemoryWithoutUpdate().unset(LEFT_LEAGUE_WHEN_GOOD_DEAL);
98 }
99 }
100 public static boolean isLeagueMember() {
101 return Global.getSector().getPlayerMemoryWithoutUpdate().getBoolean(IS_LEAGUE_MEMBER);
102 }
103 public static void setLeagueMember(boolean member) {
104 Global.getSector().getPlayerMemoryWithoutUpdate().set(IS_LEAGUE_MEMBER, member);
105 }
106
107
108 public static String KEY = "$plMembership_ref";
109 public static PerseanLeagueMembership get() {
110 return (PerseanLeagueMembership) Global.getSector().getMemoryWithoutUpdate().get(KEY);
111 }
112
113 public static String BUTTON_END = "End";
114 public static String BUTTON_RENEGE_HANNAN = "Renege Hannan";
115
116 public static String UPDATE_PARAM_ACCEPTED = "update_param_accepted";
117
118
119 protected FactionAPI faction = null;
120 protected AgreementEndingType endType = null;
121
122 public PerseanLeagueMembership(InteractionDialogAPI dialog) {
123 this.faction = Global.getSector().getFaction(Factions.PERSEAN);
124
125 setImportant(true);
126 setLeagueMember(true);
127
128 Global.getSector().getPlayerFaction().setSecondaryColorOverride(getFaction().getBaseUIColor());
129 Global.getSector().getPlayerFaction().setSecondaryColorSegmentsOverride(8);
130
131 TextPanelAPI text = null;
132 if (dialog != null) text = dialog.getTextPanel();
133
134 Global.getSector().getListenerManager().addListener(this);
135 Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
136
137 Global.getSector().getIntelManager().addIntel(this, true);
138
139 RepLevel level = faction.getRelToPlayer().getLevel();
140 if (!level.isAtWorst(RepLevel.NEUTRAL)) {
141 Misc.adjustRep(Factions.PERSEAN, 2f, RepLevel.NEUTRAL, text);
142 }
143
145 }
146
147 @Override
148 protected void notifyEnding() {
149 super.notifyEnding();
150
151 setLeagueMember(false);
153 //setPayingHouseHannan(false);
154 stopPayingHouseHannan(false, null);
155
156 Global.getSector().getMemoryWithoutUpdate().unset(KEY);
157
158 Global.getSector().getListenerManager().removeListener(this);
159 }
160
161 @Override
162 protected void notifyEnded() {
163 super.notifyEnded();
164 }
165
166 protected Object readResolve() {
167 return this;
168 }
169
170 public String getBaseName() {
171 return "Persean League Membership";
172 }
173
174 public String getAcceptedPostfix() {
175 return "Accepted";
176 }
177
178 public String getBrokenPostfix() {
179 return "Annulled";
180
181 }
182 public String getEndedPostfix() {
183 return "Ended";
184 }
185
186 public String getExpiredPostfix() {
187 return "Expired";
188 }
189
190 public String getName() {
191 String postfix = "";
192 if (isEnding() && endType != null) {
193 switch (endType) {
194 case BROKEN:
195 postfix = " - " + getBrokenPostfix();
196 break;
197 case ENDED:
198 postfix = " - " + getEndedPostfix();
199 break;
200 case EXPIRED:
201 postfix = " - " + getExpiredPostfix();
202 break;
203 }
204 }
206 postfix = " - " + getAcceptedPostfix();
207 }
208 return getBaseName() + postfix;
209 }
210
211 @Override
212 public FactionAPI getFactionForUIColors() {
213 return faction;
214 }
215
216 public String getSmallDescriptionTitle() {
217 return getName();
218 }
219
220 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
221 Color h = Misc.getHighlightColor();
222 Color g = Misc.getGrayColor();
223 float pad = 3f;
224 float opad = 10f;
225
226 float initPad = pad;
227 if (mode == ListInfoMode.IN_DESC) initPad = opad;
228
229 Color tc = getBulletColorForMode(mode);
230
231 bullet(info);
232 boolean isUpdate = getListInfoParam() != null;
233
234// if (getListInfoParam() == UPDATE_PARAM_ACCEPTED) {
235// return;
236// }
237
238 int perMonth = computeCreditsPerMonth();
239 if (perMonth != 0 && !isEnded() && !isEnding()) {
240 Color c = perMonth > 0 ? h : Misc.getNegativeHighlightColor();
241 info.addPara("%s per month", initPad, tc, c, Misc.getDGSCredits(perMonth));
242 }
243
244 unindent(info);
245 }
246
247// @Override
248// public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
249// Color h = Misc.getHighlightColor();
250// Color g = Misc.getGrayColor();
251// Color c = getTitleColor(mode);
252// float pad = 3f;
253// float opad = 10f;
254//
255// info.addPara(getName(), c, 0f);
256//
257// addBulletPoints(info, mode);
258// }
259
260 public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
261 Color h = Misc.getHighlightColor();
262 Color g = Misc.getGrayColor();
263 Color tc = Misc.getTextColor();
264 float pad = 3f;
265 float opad = 10f;
266
267 Color c = faction.getBaseUIColor();
268
269 info.addImage(getFaction().getLogo(), width, 128, opad);
270
271 if (isEnding() || isEnded()) {
272 info.addPara("Your agreement with the League is no longer in force.", opad, c, "League");
273 return;
274 }
275
276 if (isGoodDeal()) {
277 info.addPara("You've negotiated a good membership deal from a position of strength. "
278 + "The League will support you politically, which "
279 + "for example makes it untenable for the Hegemony to insist on AI inspections "
280 + "in your space.", opad, c, "League");
281
282 if (isPayingHouseHannan()) {
283 info.addPara("Part of your arrangement involves unofficial payments directly to the accounts "
284 + "of House Hannan, as payment for facilitating this agreement.", opad);
285 addBulletPoints(info, ListInfoMode.IN_DESC);
286 ButtonAPI button = info.addButton("Renege on the payments", BUTTON_RENEGE_HANNAN,
287 getFactionForUIColors().getBaseUIColor(), getFactionForUIColors().getDarkUIColor(),
288 (int)(width), 20f, opad * 1f);
289 button.setShortcut(Keyboard.KEY_G, true);
290 info.addSpacer(opad);
291 }
292 } else {
293 info.addPara("You've joined the Persean League, though it's whispered that you only did so to avoid "
294 + "harassment, and your membership dues are nothing more than protection payments. "
295 + "However, the League still supports you politically, which "
296 + "for example makes it untenable for the Hegemony to insist on AI inspections "
297 + "in your space.", opad, c, "Persean League");
298 }
299
300 info.addPara("Your League membership is contingent on maintaining an active Persean League commission. If "
301 + "you resign it, or if it is annulled for any reason, your membership will end as well.", opad);
302
304 info.addPara("You are paying membership dues to the League.", opad);
305 addBulletPoints(info, ListInfoMode.IN_DESC);
306 }
307
308
309 ButtonAPI button = info.addButton("End League membership", BUTTON_END,
310 getFactionForUIColors().getBaseUIColor(), getFactionForUIColors().getDarkUIColor(),
311 (int)(width), 20f, opad * 1f);
312 button.setShortcut(Keyboard.KEY_U, true);
313
314 }
315
316
317 public String getIcon() {
318 return faction.getCrest();
319 }
320
321 public Set<String> getIntelTags(SectorMapAPI map) {
322 Set<String> tags = super.getIntelTags(map);
323 tags.add(Tags.INTEL_AGREEMENTS);
324 tags.add(faction.getId());
325 return tags;
326 }
327
328 @Override
329 public String getImportantIcon() {
330 return Global.getSettings().getSpriteName("intel", "important_accepted_mission");
331 }
332
333 @Override
334 public SectorEntityToken getMapLocation(SectorMapAPI map) {
335 return null;
336 }
337
338
339 public void reportEconomyMonthEnd() {
340
341 }
342
343 public void reportEconomyTick(int iterIndex) {
344
345 int credits = computeCreditsPerTick();
346
347 if (credits != 0) {
348 FDNode node = getMonthlyReportNode();
349 if (credits > 0) {
350 node.income += credits;
351 } else if (credits < 0) {
352 node.upkeep -= credits;
353 }
354 }
355 }
356
357 public FDNode getMonthlyReportNode() {
358 MonthlyReport report = SharedData.getData().getCurrentReport();
359 FDNode marketsNode = report.getNode(MonthlyReport.OUTPOSTS);
360 if (marketsNode.name == null) {
361 marketsNode.name = "Colonies";
362 marketsNode.custom = MonthlyReport.OUTPOSTS;
363 marketsNode.tooltipCreator = report.getMonthlyReportTooltip();
364 }
365
366 FDNode paymentNode = report.getNode(marketsNode, "persean_league_membership");
367 paymentNode.name = "Persean League membership dues";
368 //paymentNode.upkeep += payment;
369 //paymentNode.icon = Global.getSettings().getSpriteName("income_report", "generic_expense");
370 paymentNode.icon = faction.getCrest();
371
372 if (paymentNode.tooltipCreator == null) {
373 paymentNode.tooltipCreator = new TooltipCreator() {
374 public boolean isTooltipExpandable(Object tooltipParam) {
375 return false;
376 }
377 public float getTooltipWidth(Object tooltipParam) {
378 return 450;
379 }
380 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
381 tooltip.addPara("Monthly dues for keeping your Persean League membership in good standing.", 0f);
382 }
383 };
384 }
385
386 return paymentNode;
387 }
388
390 int perTick = computeCreditsPerTick();
391 float numIter = Global.getSettings().getFloat("economyIterPerMonth");
392 return (int) (perTick * numIter);
393 }
394
395 public static int computeCreditsPerTick() {
396 float numIter = Global.getSettings().getFloat("economyIterPerMonth");
397 float f = 1f / numIter;
398
399 int payment = 0;
400 float feeFraction = Global.getSettings().getFloat("perseanLeagueFeeFraction");
401 if (isGoodDeal()) {
402 feeFraction = 0f;
403 }
404 if (isPayingHouseHannan()) {
405 feeFraction += Global.getSettings().getFloat("houseHannanFeeFraction");
406 }
407
408 for (MarketAPI market : Misc.getPlayerMarkets(false)) {
409 payment += (int) (market.getGrossIncome() * f) * feeFraction;
410 }
411
412 return -payment;
413 }
414
415 public FactionAPI getFaction() {
416 return faction;
417 }
418
419 public void endMembership(AgreementEndingType type, InteractionDialogAPI dialog) {
420 if (!isEnded() && !isEnding()) {
421 boolean baseMembership = !PerseanLeagueMembership.isGoodDeal();
422
423 endType = type;
424 setImportant(false);
425 //endAfterDelay();
427
429
430 Global.getSector().getPlayerFaction().setSecondaryColorOverride(null);
431 Global.getSector().getPlayerFaction().setSecondaryColorSegmentsOverride(0);
432
433 if (dialog != null) {
434 sendUpdate(new Object(), dialog.getTextPanel());
435 }
436
437 if (baseMembership) {
438 HA_CMD.sendPerseanLeaguePunitiveExpedition(dialog);
439 }
440
441 }
442 }
443
444
445 public static void stopPayingHouseHannan(boolean trustBroken, InteractionDialogAPI dialog) {
446 if (isPayingHouseHannan()) {
447 TextPanelAPI text = null;
448 if (dialog != null) text = dialog.getTextPanel();
449 PersonAPI reynard = People.getPerson(People.REYNARD_HANNAN);
450 if (reynard != null) {
451 Misc.adjustRep(reynard, -0.5f, text);
452 ContactIntel.removeContact(reynard, dialog);
453 }
455
456 new GensHannanMachinations(dialog);
457 if (trustBroken) {
458 Misc.incrUntrustwortyCount();
459 }
460 }
461 }
462
463 @Override
464 public void buttonPressConfirmed(Object buttonId, IntelUIAPI ui) {
465 if (buttonId == BUTTON_END) {
466 endMembership(AgreementEndingType.ENDED, null);
467 } else if (buttonId == BUTTON_RENEGE_HANNAN) {
468 stopPayingHouseHannan(true, null);
469 }
470 super.buttonPressConfirmed(buttonId, ui);
471 }
472
473
474 @Override
475 public void createConfirmationPrompt(Object buttonId, TooltipMakerAPI prompt) {
476 FactionAPI faction = getFactionForUIColors();
477
478 if (buttonId == BUTTON_END) {
479 if (isGoodDeal()) {
480 String extra = "";
481 LabelAPI label = prompt.addPara("You've negotiated a good membership deal from a position of strength. If "
482 + "you leave, you will not be allowed to rejoin, but the " +
483 faction.getDisplayNameWithArticle() + " will likely refrain "
484 + "from harassing your interests." + extra, 0f,
485 Misc.getTextColor(), faction.getBaseUIColor(),
486 faction.getDisplayNameWithArticleWithoutArticle());
487 label.setHighlightColors(Misc.getNegativeHighlightColor(), faction.getBaseUIColor());
488 label.setHighlight("will not be allowed to rejoin", faction.getDisplayNameWithArticleWithoutArticle());
489 if (isPayingHouseHannan()) {
490 prompt.addPara("However, Gens Hannan will not be pleased with their payments being stopped.",
491 10f, Misc.getNegativeHighlightColor(), "Gens Hannan will not be pleased");
492 }
493 } else {
494 String extra = "";
495 boolean canRejoin = getNumTimesLeftLeague() < TIMES_LEFT_LEAGUE_FOR_NO_REJOIN - 1;
496 float rejoinPad = 10f;
497 if (HA_CMD.canSendPerseanLeaguePunitiveExpedition()) {
498 LabelAPI label = prompt.addPara(
499 "If you leave, " + faction.getDisplayNameWithArticle() + " will likely take"
500 + " drastic action against your colonies." + extra, 0f);
501 label.setHighlightColors(faction.getBaseUIColor(), Misc.getNegativeHighlightColor());
502 label.setHighlight(faction.getDisplayNameWithArticleWithoutArticle(), "drastic action");
503 } else {
504 if (canRejoin) {
505 prompt.addPara("If you leave, " + faction.getDisplayNameWithArticle() + " will likely start "
506 + " harassing your interests in the near future.", 0f,
507 Misc.getTextColor(), faction.getBaseUIColor(),
508 faction.getDisplayNameWithArticleWithoutArticle());
509 } else {
510 rejoinPad = 0f;
511 }
512 }
513 if (!canRejoin) {
514 prompt.addPara("Given your history, it is likely that you would not be allowed "
515 + "to rejoin the League at any point in the future.",
516 rejoinPad, Misc.getNegativeHighlightColor(),
517 "would not be allowed to rejoin");
518 }
519 }
520 } else if (buttonId == BUTTON_RENEGE_HANNAN) {
521 prompt.addPara("Gens Hannan will not be pleased. While they are unlikely to be unable to obtain your outright "
522 + "explulsion from the League, their influence is significant and will likely be used "
523 + "to continually undermine your standing. ", 0f,
524 Misc.getNegativeHighlightColor(),
525 "continually undermine your standing");
526
527 prompt.addPara("You will also lose Reynard Hannan as a contact.", 10f,
528 Misc.getNegativeHighlightColor(),
529 "lose Reynard Hannan");
530 }
531 }
532
533 @Override
534 public boolean doesButtonHaveConfirmDialog(Object buttonId) {
535 if (buttonId == BUTTON_END
536 || buttonId == BUTTON_RENEGE_HANNAN) {
537 return true;
538 }
539 return super.doesButtonHaveConfirmDialog(buttonId);
540 }
541
542
544 if (intel.getFaction().getId().equals(Factions.PERSEAN)) {
545 endMembership(AgreementEndingType.BROKEN, null);
546 }
547
548 }
549}
550
551
552
553
554
555
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
void sendUpdate(Object listInfoParam, TextPanelAPI textPanel)
void createConfirmationPrompt(Object buttonId, TooltipMakerAPI prompt)
void createSmallDescription(TooltipMakerAPI info, float width, float height)
static void stopPayingHouseHannan(boolean trustBroken, InteractionDialogAPI dialog)
void endMembership(AgreementEndingType type, InteractionDialogAPI dialog)
String getSpriteName(String category, String id)