Starsector API
Loading...
Searching...
No Matches
SystemBountyIntel.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel;
2
3import java.awt.Color;
4import java.util.List;
5import java.util.Set;
6
7import org.apache.log4j.Logger;
8
9import com.fs.starfarer.api.EveryFrameScript;
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.BattleAPI;
12import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
13import com.fs.starfarer.api.campaign.CampaignFleetAPI;
14import com.fs.starfarer.api.campaign.FactionAPI;
15import com.fs.starfarer.api.campaign.LocationAPI;
16import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
17import com.fs.starfarer.api.campaign.SectorEntityToken;
18import com.fs.starfarer.api.campaign.StarSystemAPI;
19import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.ActionType;
20import com.fs.starfarer.api.campaign.econ.MarketAPI;
21import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
22import com.fs.starfarer.api.fleet.FleetMemberAPI;
23import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
24import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
25import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
26import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript;
27import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript.MilitaryResponseParams;
28import com.fs.starfarer.api.impl.campaign.econ.BaseMarketConditionPlugin;
29import com.fs.starfarer.api.impl.campaign.ids.Factions;
30import com.fs.starfarer.api.impl.campaign.ids.Tags;
31import com.fs.starfarer.api.ui.SectorMapAPI;
32import com.fs.starfarer.api.ui.TooltipMakerAPI;
33import com.fs.starfarer.api.util.Misc;
34
35public class SystemBountyIntel extends BaseIntelPlugin implements EveryFrameScript, FleetEventListener {
36 public static Logger log = Global.getLogger(SystemBountyIntel.class);
37
38 public static float MAX_DURATION = 60;
39
40 protected MarketAPI market;
41 protected LocationAPI location;
42 protected float elapsedDays = 0f;
43 protected float duration = MAX_DURATION;
44
45 protected float baseBounty = 0;
46
47 protected FactionAPI faction = null;
48 protected FactionAPI enemyFaction = null;
49 protected SystemBountyResult latestResult;
50
51 protected boolean commerceMode = false; // due to Commerce industry in player system
52
54
55 public SystemBountyIntel(MarketAPI market) {
56 this(market, -1, false);
57 }
58 public SystemBountyIntel(MarketAPI market, int baseReward, boolean commerceMode) {
59 this.market = market;
60 this.commerceMode = commerceMode;
61
62 location = market.getContainingLocation();
63 faction = market.getFaction();
64 if (commerceMode) {
65 faction = Global.getSector().getFaction(Factions.INDEPENDENT);
66 }
67
68 if (!commerceMode && market.getFaction().isPlayerFaction()) {
70 return;
71 }
72
73 baseBounty = Global.getSettings().getFloat("baseSystemBounty");
74 float marketSize = market.getSize();
75
76 baseBounty *= (marketSize + 5f) / 10f;
77
78 //float lowStabilityMult = BaseMarketConditionPlugin.getLowStabilityPenaltyMult(market);
79 float highStabilityMult = BaseMarketConditionPlugin.getHighStabilityBonusMult(market);
80 highStabilityMult = 1f + (highStabilityMult - 1f) * 0.5f;
81
82 //baseBounty *= lowStabilityMult;
83 baseBounty *= highStabilityMult;
84
85 baseBounty = (int) baseBounty;
86 if (baseReward > 0) {
87 baseBounty = baseReward;
88 }
89
90 log.info(String.format("Starting bounty at market [%s], %d credits per frigate", market.getName(), (int) baseBounty));
91
92 updateLikelyCauseFaction();
93
94
95 //conditionToken = market.addCondition(Conditions.EVENT_SYSTEM_BOUNTY, this);
96
97 if (commerceMode) {
98 Global.getSector().getIntelManager().addIntel(this);
99 } else {
100 Global.getSector().getIntelManager().queueIntel(this);
101 }
102
103 Global.getSector().getListenerManager().addListener(this);
104
105 if (!commerceMode) {
106 MilitaryResponseParams params = new MilitaryResponseParams(ActionType.HOSTILE,
107 "system_bounty_" + market.getId(),
109 market.getPrimaryEntity(),
110 0.75f,
111 duration);
112 script = new MilitaryResponseScript(params);
113 location.addScript(script);
114 }
115 }
116
118 if (!isEnding() && !isEnded()) {
119 duration = Math.max(duration * 0.5f, Math.min(duration * 2f, MAX_DURATION));
120 }
121 }
122
123 public float getElapsedDays() {
124 return elapsedDays;
125 }
126
127 public void setElapsedDays(float elapsedDays) {
128 this.elapsedDays = elapsedDays;
129 }
130
131 public void reset() {
132 elapsedDays = 0f;
133 endingTimeRemaining = null;
134 ending = null;
135 ended = null;
136 script.setElapsed(0f);
137 if (!Global.getSector().getListenerManager().hasListener(this)) {
138 Global.getSector().getListenerManager().addListener(this);
139 }
140 }
141
142
143
144 public MarketAPI getMarket() {
145 return market;
146 }
147
148
149 private void updateLikelyCauseFaction() {
150 int maxSize = 0;
151 MarketAPI maxOther = null;
152 for (MarketAPI other : Misc.getNearbyMarkets(market.getLocationInHyperspace(), 0f)) {
153 if (market.getFaction() == other.getFaction()) continue;
154 if (!market.getFaction().isHostileTo(other.getFaction())) continue;
155
156 int size = other.getSize();
157 if (size > maxSize) {
158 maxSize = size;
159 maxOther = other;
160 }
161 }
162
163 if (maxOther != null) {
164 enemyFaction = maxOther.getFaction();
165 } else {
166 enemyFaction = Global.getSector().getFaction(Factions.PIRATES);
167 }
168
169 }
170
171 @Override
172 protected void advanceImpl(float amount) {
173 float days = Global.getSector().getClock().convertToDays(amount);
174
175 elapsedDays += days;
176
177 if (elapsedDays >= duration && !isDone() && !commerceMode) {
179 boolean current = market.getContainingLocation() == Global.getSector().getCurrentLocation();
180 sendUpdateIfPlayerHasIntel(new Object(), !current);
181 return;
182 }
183 if (faction != market.getFaction() || !market.isInEconomy()) {
185 boolean current = market.getContainingLocation() == Global.getSector().getCurrentLocation();
186 sendUpdateIfPlayerHasIntel(new Object(), !current);
187 return;
188 }
189 }
190
192 if (commerceMode) return 1f;
193 float f = 1f - elapsedDays / duration;
194 return f;
195 }
196
197
198
199 @Override
200 protected void notifyEnding() {
201 super.notifyEnding();
202 log.info(String.format("Ending bounty at market [%s]", market.getName()));
203
204 Global.getSector().getListenerManager().removeListener(this);
205
206 location.removeScript(script);
207
208 //market.removeSpecificCondition(conditionToken);
209 }
210
211
212 public static class SystemBountyResult {
213 public int payment;
214 public float fraction;
215 public ReputationAdjustmentResult rep;
216 public SystemBountyResult(int payment, float fraction, ReputationAdjustmentResult rep) {
217 this.payment = payment;
218 this.fraction = fraction;
219 this.rep = rep;
220 }
221
222 }
223
224 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
225 }
226
227 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
228 if (isEnded() || isEnding()) return;
229
230 if (!battle.isPlayerInvolved()) return;
231
232 if (!Misc.isNear(primaryWinner, market.getLocationInHyperspace())) return;
233
234 int payment = 0;
235 float fpDestroyed = 0;
236 for (CampaignFleetAPI otherFleet : battle.getNonPlayerSideSnapshot()) {
237 if (commerceMode) {
238 if (!market.getFaction().isHostileTo(otherFleet.getFaction()) &&
239 !otherFleet.getFaction().isHostileTo(Factions.INDEPENDENT)) continue;
240
241 if (Misc.isTrader(otherFleet)) continue;
242 if (Factions.INDEPENDENT.equals(otherFleet.getFaction().getId())) continue;
243 } else {
244 if (!market.getFaction().isHostileTo(otherFleet.getFaction())) continue;
245 }
246
247 float bounty = 0;
248 for (FleetMemberAPI loss : Misc.getSnapshotMembersLost(otherFleet)) {
249 float mult = Misc.getSizeNum(loss.getHullSpec().getHullSize());
250 bounty += mult * baseBounty;
251 fpDestroyed += loss.getFleetPointCost();
252 }
253
254 payment += (int) (bounty * battle.getPlayerInvolvementFraction());
255 }
256
257 if (payment > 0) {
258 Global.getSector().getPlayerFleet().getCargo().getCredits().add(payment);
259
260 float repFP = (int)(fpDestroyed * battle.getPlayerInvolvementFraction());
261 ReputationAdjustmentResult rep = Global.getSector().adjustPlayerReputation(
262 new RepActionEnvelope(RepActions.SYSTEM_BOUNTY_REWARD, new Float(repFP), null, null, true, false),
263 market.getFaction().getId());
264 latestResult = new SystemBountyResult(payment, battle.getPlayerInvolvementFraction(), rep);
266 }
267 }
268
269 public boolean runWhilePaused() {
270 return false;
271 }
272 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
273
274 Color h = Misc.getHighlightColor();
275 Color g = Misc.getGrayColor();
276 float pad = 3f;
277 float opad = 10f;
278
279 float initPad = pad;
280 if (mode == ListInfoMode.IN_DESC) initPad = opad;
281
282 Color tc = getBulletColorForMode(mode);
283
284 bullet(info);
285 boolean isUpdate = getListInfoParam() != null;
286
287 if (isEnding() && isUpdate) {
288 //info.addPara("Over", initPad);
289 } else {
290 if (isUpdate && latestResult != null) {
291 info.addPara("%s received", initPad, tc, h, Misc.getDGSCredits(latestResult.payment));
292 if (Math.round(latestResult.fraction * 100f) < 100f) {
293 info.addPara("%s share based on damage dealt", 0f, tc, h,
294 "" + (int) Math.round(latestResult.fraction * 100f) + "%");
295 }
297 null, null, info, tc, isUpdate, 0f);
298 } else if (mode == ListInfoMode.IN_DESC) {
299 info.addPara("%s base reward per frigate", initPad, tc, h, Misc.getDGSCredits(baseBounty));
300 if (!commerceMode) {
301 addDays(info, "remaining", duration - elapsedDays, tc);
302 }
303 } else {
304 if (!isEnding()) {
305 info.addPara("Faction: " + faction.getDisplayName(), initPad, tc,
306 faction.getBaseUIColor(), faction.getDisplayName());
307 info.addPara("%s base reward per frigate", 0f, tc, h, Misc.getDGSCredits(baseBounty));
308 if (!commerceMode) {
309 addDays(info, "remaining", duration - elapsedDays, tc);
310 }
311 }
312 }
313 }
314 unindent(info);
315 }
316
317 @Override
318 public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
319 Color h = Misc.getHighlightColor();
320 Color g = Misc.getGrayColor();
321 Color c = getTitleColor(mode);
322 float pad = 3f;
323 float opad = 10f;
324
325 info.addPara(getName(), c, 0f);
326
327 addBulletPoints(info, mode);
328 }
329
330 public String getSortString() {
331 return "System Bounty";
332 }
333
334 public String getName() {
335 String name = market.getName();
336 StarSystemAPI system = market.getStarSystem();
337 if (system != null) {
338 name = system.getBaseName();
339 }
340 if (isEnding()) {
341 return "Bounty Ended - " + name;
342 }
343 return "System Bounty - " + name;
344 }
345
346 @Override
347 public FactionAPI getFactionForUIColors() {
348 return faction;
349 }
350
351 public String getSmallDescriptionTitle() {
352 return getName();
353 //return null;
354 }
355
356 public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
357 createSmallDescription(info, width, height, false);
358 }
359 public void createSmallDescription(TooltipMakerAPI info, float width, float height,
360 boolean forMarketConditionTooltip) {
361 Color h = Misc.getHighlightColor();
362 Color g = Misc.getGrayColor();
363 Color tc = Misc.getTextColor();
364 float pad = 3f;
365 float opad = 10f;
366
367 //info.addPara(getName(), c, 0f);
368
369 //info.addSectionHeading(getName(), Alignment.MID, 0f);
370
371 if (!forMarketConditionTooltip) {
372 info.addImage(faction.getLogo(), width, 128, opad);
373 }
374
375 String locStr = "near " + market.getName();
376 if (market.getStarSystem() != null) {
377 locStr = "in or near the " + market.getStarSystem().getNameWithLowercaseType();
378 }
379
380 if (commerceMode) {
381 info.addPara("%s commercial concerns " + market.getOnOrAt() + " " + market.getName() +
382 " have banded together and posted a modest but long-term bounty on all "
383 + "hostile fleets " + locStr + ".",
384 opad, faction.getBaseUIColor(), Misc.ucFirst(faction.getPersonNamePrefix()));
385 info.addPara("The bounty stipulates that trade fleets are an exception - "
386 + "attacking them will not result in a reward, regardless of their faction.", opad);
387 } else {
388 info.addPara("%s authorities " + market.getOnOrAt() + " " + market.getName() +
389 " have posted a bounty on all hostile fleets " + locStr + ".",
390 opad, faction.getBaseUIColor(), Misc.ucFirst(faction.getPersonNamePrefix()));
391 }
392
393 if (isEnding()) {
394 info.addPara("This bounty is no longer on offer.", opad);
395 return;
396 }
397
398// if (!Global.getSector().getListenerManager().hasListener(this)) {
399// Global.getSector().getListenerManager().addListener(this);
400// info.addPara("Listener not registered!", opad);
401// }
402
403 addBulletPoints(info, ListInfoMode.IN_DESC);
404
405 if (!commerceMode) {
406 if (enemyFaction != null) {
407 info.addPara("Likely triggered by %s activity.",
408 opad, enemyFaction.getBaseUIColor(), enemyFaction.getPersonNamePrefix());
409 }
410 } else {
411 info.addPara("Triggered by the presence of Commerce on one of your colonies in-system, and by the "
412 + "level of hostile activity.", opad);
413 }
414
415
416 info.addPara("Payment depends on the number and size of ships destroyed. " +
417 "Standing with " + faction.getDisplayNameWithArticle() + " may also improve.",
418 opad);
419// opad, faction.getBaseUIColor(),
420// faction.getDisplayNameWithArticleWithoutArticle());
421
422
423 if (!commerceMode) {
424 String isOrAre = faction.getDisplayNameIsOrAre();
426 List<FactionAPI> hostile = temp.getHostileFactions();
427 if (hostile.isEmpty()) {
428 info.addPara(Misc.ucFirst(faction.getDisplayNameWithArticle()) + " " + isOrAre + " not currently hostile to any major factions.", 0f);
429 } else {
430 info.addPara(Misc.ucFirst(faction.getDisplayNameWithArticle()) + " " + isOrAre + " currently hostile to:", opad);
431
432 info.setParaFontDefault();
433
434 info.setBulletedListMode(BaseIntelPlugin.INDENT);
435 float initPad = pad;
436 for (FactionAPI other : hostile) {
437 info.addPara(Misc.ucFirst(other.getDisplayName()), other.getBaseUIColor(), initPad);
438 initPad = 0f;
439 }
440 info.setBulletedListMode(null);
441 }
442 }
443
444 if (latestResult != null) {
445 //Color color = faction.getBaseUIColor();
446 //Color dark = faction.getDarkUIColor();
447 //info.addSectionHeading("Most Recent Reward", color, dark, Alignment.MID, opad);
448 info.addPara("Most recent bounty:", opad);
449 bullet(info);
450 info.addPara("%s received", pad, tc, h, Misc.getDGSCredits(latestResult.payment));
451 if (Math.round(latestResult.fraction * 100f) < 100f) {
452 info.addPara("%s share based on damage dealt", 0f, tc, h,
453 "" + (int) Math.round(latestResult.fraction * 100f) + "%");
454 }
456 null, null, info, tc, false, 0f);
457 unindent(info);
458 }
459
460 }
461
462 public String getIcon() {
463 return Global.getSettings().getSpriteName("intel", "system_bounty");
464 }
465
466 public Set<String> getIntelTags(SectorMapAPI map) {
467 Set<String> tags = super.getIntelTags(map);
468 tags.add(Tags.INTEL_BOUNTY);
469 tags.add(faction.getId());
470 return tags;
471 }
472
473 @Override
474 public SectorEntityToken getMapLocation(SectorMapAPI map) {
475 return market.getPrimaryEntity();
476 }
477
478
479 public float getDuration() {
480 return duration;
481 }
482
483 public void setDuration(float duration) {
484 this.duration = duration;
485 }
486
487 public float getBaseBounty() {
488 return baseBounty;
489 }
490
491 public void setBaseBounty(float baseBounty) {
492 this.baseBounty = baseBounty;
493 }
494 public boolean isCommerceMode() {
495 return commerceMode;
496 }
497
498 public void setCommerceMode(boolean commerceMode) {
499 this.commerceMode = commerceMode;
500 }
501 public LocationAPI getLocation() {
502 return location;
503 }
504
505}
506
507
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 addAdjustmentMessage(float delta, FactionAPI faction, PersonAPI person, TextPanelAPI panel, TooltipMakerAPI info, Color tc, boolean withCurrent, float pad)
void addDays(TooltipMakerAPI info, String after, float days)
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
void createSmallDescription(TooltipMakerAPI info, float width, float height, boolean forMarketConditionTooltip)
void createSmallDescription(TooltipMakerAPI info, float width, float height)
void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
SystemBountyIntel(MarketAPI market, int baseReward, boolean commerceMode)
void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode)
String getSpriteName(String category, String id)