Starsector API
Loading...
Searching...
No Matches
FactionCommissionIntel.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.LinkedHashMap;
6import java.util.LinkedHashSet;
7import java.util.List;
8import java.util.Set;
9
10import org.apache.log4j.Logger;
11
12import com.fs.starfarer.api.EveryFrameScript;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.BattleAPI;
15import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
16import com.fs.starfarer.api.campaign.CampaignFleetAPI;
17import com.fs.starfarer.api.campaign.FactionAPI;
18import com.fs.starfarer.api.campaign.InteractionDialogAPI;
19import com.fs.starfarer.api.campaign.RepLevel;
20import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
21import com.fs.starfarer.api.campaign.SectorEntityToken;
22import com.fs.starfarer.api.campaign.econ.MarketAPI;
23import com.fs.starfarer.api.campaign.econ.MonthlyReport;
24import com.fs.starfarer.api.campaign.econ.MonthlyReport.FDNode;
25import com.fs.starfarer.api.campaign.listeners.EconomyTickListener;
26import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
27import com.fs.starfarer.api.campaign.listeners.ListenerUtil;
28import com.fs.starfarer.api.fleet.FleetMemberAPI;
29import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
30import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
31import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
32import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
33import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
34import com.fs.starfarer.api.impl.campaign.ids.Tags;
35import com.fs.starfarer.api.impl.campaign.rulecmd.missions.Commission;
36import com.fs.starfarer.api.impl.campaign.shared.SharedData;
37import com.fs.starfarer.api.ui.SectorMapAPI;
38import com.fs.starfarer.api.ui.TooltipMakerAPI;
39import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
40import com.fs.starfarer.api.util.Misc;
41
43 FleetEventListener, EconomyTickListener {
44 public static Logger log = Global.getLogger(FactionCommissionIntel.class);
45
46 public static String UPDATE_PARAM_ACCEPTED = "update_param_accepted";
47
48 public static class CommissionBountyResult extends MissionResult {
49 public float fraction;
50 public CommissionBountyResult(int payment, float fraction, ReputationAdjustmentResult rep) {
51 super(payment, rep);
52 this.fraction = fraction;
53 }
54 }
55
56 public static class RepChangeData {
57 public FactionAPI faction;
58 public float delta;
59 }
60
61
62 protected float baseBounty = 0;
63 protected FactionAPI faction = null;
64 //protected FactionCommissionPlugin plugin = null;
65
66 protected CommissionBountyResult latestResult;
67
68 protected LinkedHashMap<String, RepChangeData> repChanges = new LinkedHashMap<String, RepChangeData>();
69
70 public FactionCommissionIntel(FactionAPI faction) {
71 this.faction = faction;
72 baseBounty = Global.getSettings().getFloat("factionCommissionBounty");
73 }
74
75 protected Object readResolve() {
76 baseBounty = Global.getSettings().getFloat("factionCommissionBounty");
77 return this;
78 }
79
80 @Override
81 public void advanceMission(float amount) {
82 float days = Global.getSector().getClock().convertToDays(amount);
83
84 RepLevel level = faction.getRelToPlayer().getLevel();
85 if (!level.isAtWorst(RepLevel.NEUTRAL)) {
86 setMissionResult(new MissionResult(-1, null));
87 setMissionState(MissionState.COMPLETED);
88 endMission();
90 } else {
91 makeRepChanges(null);
92 }
93 }
94
95
96 @Override
97 public void missionAccepted() {
98 log.info(String.format("Accepted commission with [%s]", faction.getDisplayName(), (int) baseBounty));
99
100 setImportant(true);
101 setMissionState(MissionState.ACCEPTED);
102
103 Global.getSector().getIntelManager().addIntel(this, true);
104 Global.getSector().getListenerManager().addListener(this);
105 Global.getSector().addScript(this);
106
107 Global.getSector().getCharacterData().getMemoryWithoutUpdate().set(MemFlags.FCM_FACTION, faction.getId());
108 Global.getSector().getCharacterData().getMemoryWithoutUpdate().set(MemFlags.FCM_EVENT, this);
109 }
110
111 @Override
112 public void endMission() {
113 endMission(null);
114 }
115 public void endMission(InteractionDialogAPI dialog) {
116 log.info(String.format("Ending commission with [%s]", faction.getDisplayName()));
117 Global.getSector().getListenerManager().removeListener(this);
118 Global.getSector().removeScript(this);
119
120 Global.getSector().getCharacterData().getMemoryWithoutUpdate().unset(MemFlags.FCM_FACTION);
121 Global.getSector().getCharacterData().getMemoryWithoutUpdate().unset(MemFlags.FCM_EVENT);
122
123 undoAllRepChanges(dialog);
124
125 //endAfterDelay();
127
128 ListenerUtil.reportCommissionEnded(this);
129 }
130
131 public void makeRepChanges(InteractionDialogAPI dialog) {
132 FactionAPI player = Global.getSector().getPlayerFaction();
133 for (FactionAPI other : getRelevantFactions()) {
134 RepChangeData change = repChanges.get(other.getId());
135
136 boolean madeHostile = change != null;
137 boolean factionHostile = faction.isHostileTo(other);
138 boolean playerHostile = player.isHostileTo(other);
139
140 if (factionHostile && !playerHostile && !madeHostile) {
141 makeHostile(other, dialog);
142 }
143
144 if (!factionHostile && madeHostile) {
145 undoRepChange(other, dialog);
146 }
147 }
148 }
149
150 public void makeHostile(FactionAPI other, InteractionDialogAPI dialog) {
151 ReputationAdjustmentResult rep = Global.getSector().adjustPlayerReputation(
152 new RepActionEnvelope(RepActions.MAKE_HOSTILE_AT_BEST,
153 null, null, dialog != null ? dialog.getTextPanel() : null, false, true),
154 other.getId());
155
156 RepChangeData data = new RepChangeData();
157 data.faction = other;
158 data.delta = rep.delta;
159 repChanges.put(other.getId(), data);
160 }
161
162 public void undoRepChange(FactionAPI other, InteractionDialogAPI dialog) {
163 String id = other.getId();
164 RepChangeData change = repChanges.get(id);
165
166 if (change == null) return;
167
168 CustomRepImpact impact = new CustomRepImpact();
169 impact.delta = -change.delta;
170 impact.delta = Math.max(0f, impact.delta - Global.getSettings().getFloat("factionCommissionRestoredRelationshipPenalty"));
171 if (impact.delta > 0) {
172 Global.getSector().adjustPlayerReputation(
173 new RepActionEnvelope(RepActions.CUSTOM,
174 impact, null, dialog != null ? dialog.getTextPanel() : null, false, true),
175 id);
176 }
177 repChanges.remove(id);
178 }
179
180 public void undoAllRepChanges(InteractionDialogAPI dialog) {
181 for (RepChangeData data : new ArrayList<RepChangeData>(repChanges.values())) {
182 undoRepChange(data.faction, dialog);
183 }
184 }
185
186
187 public List<FactionAPI> getRelevantFactions() {
188 Set<FactionAPI> factions = new LinkedHashSet<FactionAPI>();
189 for (MarketAPI market : Global.getSector().getEconomy().getMarketsCopy()) {
190 if (market.isHidden()) continue;
191 FactionAPI curr = market.getFaction();
192 if (factions.contains(curr)) continue;
193
194 if (curr.isShowInIntelTab()) {
195 factions.add(curr);
196 }
197 }
198
199 return new ArrayList<FactionAPI>(factions);
200 }
201 public List<FactionAPI> getHostileFactions() {
202 FactionAPI player = Global.getSector().getPlayerFaction();
203 List<FactionAPI> hostile = new ArrayList<FactionAPI>();
204 for (FactionAPI other : getRelevantFactions()) {
205 if (this.faction.isHostileTo(other)) {
206 hostile.add(other);
207 }
208 }
209 return hostile;
210 }
211
212
213 public float computeStipend() {
214 float level = Global.getSector().getPlayerPerson().getStats().getLevel();
215
216 return Global.getSettings().getFloat("factionCommissionStipendBase") +
217 Global.getSettings().getFloat("factionCommissionStipendPerLevel") * level;
218 }
219
220 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
221 }
222
223 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
224 if (isEnded() || isEnding()) return;
225
226 if (!battle.isPlayerInvolved()) return;
227
228 int payment = 0;
229 float fpDestroyed = 0;
230 for (CampaignFleetAPI otherFleet : battle.getNonPlayerSideSnapshot()) {
231 if (!faction.isHostileTo(otherFleet.getFaction())) continue;
232
233 float bounty = 0;
234 for (FleetMemberAPI loss : Misc.getSnapshotMembersLost(otherFleet)) {
235 float mult = Misc.getSizeNum(loss.getHullSpec().getHullSize());
236 bounty += mult * baseBounty;
237 fpDestroyed += loss.getFleetPointCost();
238 }
239
240 payment += (int) (bounty * battle.getPlayerInvolvementFraction());
241 }
242
243 if (payment > 0) {
244 Global.getSector().getPlayerFleet().getCargo().getCredits().add(payment);
245
246 float repFP = (int)(fpDestroyed * battle.getPlayerInvolvementFraction());
247 ReputationAdjustmentResult rep = Global.getSector().adjustPlayerReputation(
248 new RepActionEnvelope(RepActions.COMMISSION_BOUNTY_REWARD, new Float(repFP), null, null, true, false),
249 faction.getId());
250 latestResult = new CommissionBountyResult(payment, battle.getPlayerInvolvementFraction(), rep);
252 }
253 }
254
255 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
256
257 Color h = Misc.getHighlightColor();
258 Color g = Misc.getGrayColor();
259 float pad = 3f;
260 float opad = 10f;
261
262 float initPad = pad;
263 if (mode == ListInfoMode.IN_DESC) initPad = opad;
264
265 Color tc = getBulletColorForMode(mode);
266
267 bullet(info);
268 boolean isUpdate = getListInfoParam() != null;
269
271 return;
272 }
273
274 if (missionResult != null && missionResult.payment < 0) {
275// info.addPara("Annulled by " + faction.getDisplayNameWithArticle(), initPad, tc,
276// faction.getBaseUIColor(), faction.getDisplayNameWithArticleWithoutArticle());
277 } else if (isUpdate && latestResult != null) {
278 info.addPara("%s received", initPad, tc, h, Misc.getDGSCredits(latestResult.payment));
279 if (Math.round(latestResult.fraction * 100f) < 100f) {
280 info.addPara("%s share based on damage dealt", 0f, tc, h,
281 "" + (int) Math.round(latestResult.fraction * 100f) + "%");
282 }
284 null, null, info, tc, isUpdate, 0f);
285 } else if (mode == ListInfoMode.IN_DESC) {
286 info.addPara("%s base bounty per hostile frigate", initPad, tc, h, Misc.getDGSCredits(baseBounty));
287 info.addPara("%s monthly stipend", 0f, tc, h, Misc.getDGSCredits(computeStipend()));
288 } else {
289// info.addPara("Faction: " + faction.getDisplayName(), initPad, tc,
290// faction.getBaseUIColor(), faction.getDisplayName());
291// initPad = 0f;
292 info.addPara("%s base reward per frigate", initPad, tc, h, Misc.getDGSCredits(baseBounty));
293 info.addPara("%s monthly stipend", 0f, tc, h, Misc.getDGSCredits(computeStipend()));
294 }
295 unindent(info);
296 }
297
298 @Override
299 public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
300 Color h = Misc.getHighlightColor();
301 Color g = Misc.getGrayColor();
302 Color c = getTitleColor(mode);
303 float pad = 3f;
304 float opad = 10f;
305
306 info.addPara(getName(), c, 0f);
307
308 addBulletPoints(info, mode);
309 }
310
311 public String getSortString() {
312 return "Commission";
313 }
314
315 public String getName() {
316 String prefix = Misc.ucFirst(faction.getPersonNamePrefix()) + " Commission";
317// if (plugin != null) {
318// String override = plugin.getNameOverride();
319// if (override != null) {
320// prefix = override;
321// }
322// }
323 if (isEnding()) {
324 if (missionResult != null && missionResult.payment < 0) {
325 if (isSendingUpdate()) {
326 return prefix + " - Annulled";
327 }
328 return prefix + " - Annulled";
329 //return prefix + " (Annulled)";
330 }
331 //return prefix + " (Resigned)";
332 return prefix + " - Resigned";
333 }
335 //return prefix + " Accepted";
336 return prefix + " - Accepted";
337 }
338 return prefix;
339 }
340
341 @Override
342 public FactionAPI getFactionForUIColors() {
343 return faction;
344 }
345
346 public FactionAPI getFaction() {
347 return faction;
348 }
349
350 public String getSmallDescriptionTitle() {
351 return getName();
352 }
353
354 public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
355 createSmallDescription(info, width, height, false);
356 }
357 public void createSmallDescription(TooltipMakerAPI info, float width, float height,
358 boolean forMarketConditionTooltip) {
359 Color h = Misc.getHighlightColor();
360 Color g = Misc.getGrayColor();
361 Color tc = Misc.getTextColor();
362 float pad = 3f;
363 float opad = 10f;
364
365 info.addImage(faction.getLogo(), width, 128, opad);
366
367
368 if (isEnding()) {
369 if (missionResult != null && missionResult.payment < 0) {
370 info.addPara("Your commission was annulled by " + faction.getDisplayNameWithArticle() +
371 " due to your standing falling too low.",
372 opad, faction.getBaseUIColor(),
373 faction.getDisplayNameWithArticleWithoutArticle());
374
375 CoreReputationPlugin.addRequiredStanding(faction, Commission.COMMISSION_REQ, null, null, info, tc, opad, true);
376 CoreReputationPlugin.addCurrentStanding(faction, null, null, info, tc, opad);
377 } else {
378 info.addPara("You've resigned your commission with " + faction.getDisplayNameWithArticle() +
379 ".",
380 opad, faction.getBaseUIColor(),
381 faction.getDisplayNameWithArticleWithoutArticle());
382 }
383 } else {
384 info.addPara("You've accepted a %s commission.",
385 opad, faction.getBaseUIColor(), Misc.ucFirst(faction.getPersonNamePrefix()));
386
387 addBulletPoints(info, ListInfoMode.IN_DESC);
388
389 info.addPara("The combat bounty payment depends on the number and size of ships destroyed.", opad);
390 }
391
392 if (latestResult != null) {
393 //Color color = faction.getBaseUIColor();
394 //Color dark = faction.getDarkUIColor();
395 //info.addSectionHeading("Most Recent Reward", color, dark, Alignment.MID, opad);
396 info.addPara("Most recent bounty:", opad);
397 bullet(info);
398 info.addPara("%s received", opad, tc, h, Misc.getDGSCredits(latestResult.payment));
399 if (Math.round(latestResult.fraction * 100f) < 100f) {
400 info.addPara("%s share based on damage dealt", 0f, tc, h,
401 "" + (int) Math.round(latestResult.fraction * 100f) + "%");
402 }
404 null, null, info, tc, false, 0f);
405 unindent(info);
406 }
407
408 if (!isEnding() && !isEnded()) {
409 boolean plMember = PerseanLeagueMembership.isLeagueMember();
410 if (!plMember) {
411 addAbandonButton(info, width, "Resign commission");
412 } else {
413 info.addPara("You can not resign your commission while polities under your "
414 + "control are members of the League.", opad);
415 }
416 }
417 }
418
419 public String getIcon() {
420 return faction.getCrest();
421 }
422
423 public Set<String> getIntelTags(SectorMapAPI map) {
424 Set<String> tags = super.getIntelTags(map);
425 tags.remove(Tags.INTEL_ACCEPTED);
426 tags.remove(Tags.INTEL_MISSIONS);
427 //tags.add(Tags.INTEL_COMMISSION);
428 tags.add(Tags.INTEL_AGREEMENTS);
429 tags.add(faction.getId());
430 return tags;
431 }
432
433 @Override
434 public SectorEntityToken getMapLocation(SectorMapAPI map) {
435 return null;
436 }
437
438 @Override
439 protected MissionResult createAbandonedResult(boolean withPenalty) {
440 return createResignedCommissionResult(true, false, null);
441 }
442
443 public MissionResult createResignedCommissionResult(boolean withPenalty, boolean inPerson, InteractionDialogAPI dialog) {
444 if (withPenalty) {
445 CustomRepImpact impact = new CustomRepImpact();
446 impact.delta = -1f * Global.getSettings().getFloat("factionCommissionResignPenalty");
447 if (inPerson) {
448 impact.delta = -1f * Global.getSettings().getFloat("factionCommissionResignPenaltyInPerson");
449 }
450 ReputationAdjustmentResult rep = Global.getSector().adjustPlayerReputation(
451 new RepActionEnvelope(RepActions.CUSTOM,
452 impact, null, dialog != null ? dialog.getTextPanel() : null, false, true),
453 faction.getId());
454 return new MissionResult();
455 }
456 return new MissionResult();
457 }
458
459 @Override
460 protected MissionResult createTimeRanOutFailedResult() {
461 return new MissionResult();
462 }
463
464 @Override
465 protected String getMissionTypeNoun() {
466 return "commission";
467 }
468
469 @Override
470 protected float getNoPenaltyAbandonDays() {
471 return 0f;
472 }
473
474
475
476 public void reportEconomyMonthEnd() {
477// if (plugin != null) {
478// plugin.reportEconomyMonthEnd();
479// }
480 }
481
482 public void reportEconomyTick(int iterIndex) {
483
484 float numIter = Global.getSettings().getFloat("economyIterPerMonth");
485 float f = 1f / numIter;
486
487 //CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
488 MonthlyReport report = SharedData.getData().getCurrentReport();
489
490 FDNode fleetNode = report.getNode(MonthlyReport.FLEET);
491 fleetNode.name = "Fleet";
492 fleetNode.custom = MonthlyReport.FLEET;
493 fleetNode.tooltipCreator = report.getMonthlyReportTooltip();
494
495 float stipend = computeStipend();
496 FDNode stipendNode = report.getNode(fleetNode, "node_id_stipend_" + faction.getId());
497 stipendNode.income += stipend * f;
498
499 if (stipendNode.name == null) {
500 stipendNode.name = faction.getDisplayName() + " Commission";
501 stipendNode.icon = faction.getCrest();
502 stipendNode.tooltipCreator = new TooltipCreator() {
503 public boolean isTooltipExpandable(Object tooltipParam) {
504 return false;
505 }
506 public float getTooltipWidth(Object tooltipParam) {
507 return 450;
508 }
509 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
510 tooltip.addPara("Your monthly stipend for holding a " + faction.getDisplayName() + " commission", 0f);
511 }
512 };
513 }
514
515// if (plugin != null) {
516// plugin.reportEconomyTick(iterIndex);
517// }
518 }
519
520// public FactionCommissionPlugin getPlugin() {
521// return plugin;
522// }
523//
524// public void setPlugin(FactionCommissionPlugin plugin) {
525// this.plugin = plugin;
526// }
527
528
529}
530
531
532
533
534
535
static SettingsAPI getSettings()
Definition Global.java:51
static Logger getLogger(Class c)
Definition Global.java:26
static SectorAPI getSector()
Definition Global.java:59
static void addRequiredStanding(FactionAPI faction, RepLevel req, PersonAPI person, TextPanelAPI panel, TooltipMakerAPI info, Color tc, float pad, boolean orBetter)
static void addAdjustmentMessage(float delta, FactionAPI faction, PersonAPI person, TextPanelAPI panel, TooltipMakerAPI info, Color tc, boolean withCurrent, float pad)
static void addCurrentStanding(FactionAPI faction, PersonAPI person, TextPanelAPI panel, TooltipMakerAPI info, Color tc, float pad)
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
void addAbandonButton(TooltipMakerAPI info, float width)
void createSmallDescription(TooltipMakerAPI info, float width, float height)
void makeHostile(FactionAPI other, InteractionDialogAPI dialog)
void undoRepChange(FactionAPI other, InteractionDialogAPI dialog)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
void createSmallDescription(TooltipMakerAPI info, float width, float height, boolean forMarketConditionTooltip)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
MissionResult createResignedCommissionResult(boolean withPenalty, boolean inPerson, InteractionDialogAPI dialog)