Starsector API
Loading...
Searching...
No Matches
FoodShortageEvent.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.events;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.List;
6import java.util.Map;
7
8import org.apache.log4j.Logger;
9
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.Script;
12import com.fs.starfarer.api.campaign.BaseOnMessageDeliveryScript;
13import com.fs.starfarer.api.campaign.CampaignFleetAPI;
14import com.fs.starfarer.api.campaign.FleetAssignment;
15import com.fs.starfarer.api.campaign.InteractionDialogAPI;
16import com.fs.starfarer.api.campaign.LocationAPI;
17import com.fs.starfarer.api.campaign.PlayerMarketTransaction;
18import com.fs.starfarer.api.campaign.SectorEntityToken;
19import com.fs.starfarer.api.campaign.StarSystemAPI;
20import com.fs.starfarer.api.campaign.SubmarketPlugin;
21import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
22import com.fs.starfarer.api.campaign.comm.CommMessageAPI;
23import com.fs.starfarer.api.campaign.comm.MessagePriority;
24import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
25import com.fs.starfarer.api.campaign.econ.MarketAPI;
26import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
27import com.fs.starfarer.api.campaign.events.CampaignEventManagerAPI;
28import com.fs.starfarer.api.campaign.events.CampaignEventTarget;
29import com.fs.starfarer.api.campaign.events.EventProbabilityAPI;
30import com.fs.starfarer.api.campaign.rules.MemKeys;
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.fleets.FleetFactory;
34import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
35import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
36import com.fs.starfarer.api.impl.campaign.ids.Commodities;
37import com.fs.starfarer.api.impl.campaign.ids.Conditions;
38import com.fs.starfarer.api.impl.campaign.ids.Events;
39import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
40import com.fs.starfarer.api.impl.campaign.rulecmd.FireBest;
41import com.fs.starfarer.api.impl.campaign.shared.SharedData;
42import com.fs.starfarer.api.util.Misc;
43
44public class FoodShortageEvent extends BaseEventPlugin {
45
46 public static Logger log = Global.getLogger(FoodShortageEvent.class);
47
48 public static String PRICE_MOD_ID = "fse_priceMod";
49
50 public static float FOOD_PRICE_MULT = 1.5f;
51 public static float FOOD_PRICE_FLAT = 50f;
52
53 public static float MAX_POSSIBLE_DURATION = 60f;
54 public static float MIN_FRACTION_FOR_PLAYER_ENDING_EVENT = 0.5f;
55
56
57 public static enum Ending {
58 DURATION_EXPIRED,
59 RELIEF_ARRIVED,
60 PLAYER_ENDED,
61 PLAYER_ENDED_BLACK,
62 }
63
64 public static class PlayerFoodTransaction {
65 public long timestamp;
66
70 public float quantity;
71 }
72
73 private boolean ended = false;
74
75 private float maxDurationDays;
76 private float daysBeforeReliefCheck;
77 private float daysBeforeReliefSend;
78 private float elapsedDays = 0f;
79 private int stage = 0;
80
81 //private List<PlayerFoodTransaction> preEventTransactions = new ArrayList<PlayerFoodTransaction>();
82 private float preEventFoodLevel;
83
84 //private float foodToMeetShortage = 0;
85 private float baseFoodToMeetShortage = 0;
86 //private float playerBlameAmount = 0;
87 private float netDeliveredByPlayerBlack = 0;
88 private float netDeliveredByPlayerOther = 0;
89
90 //private float originalReliefFleetCargoCapacity = 0;
91 private float originalReliefFleetPoints = 0;
92 private CampaignFleetAPI reliefFleet;
93
94 private MessagePriority messagePriority = MessagePriority.CLUSTER;
95 private String foodShortageConditionToken = null;
96
97 private MarketAPI reliefMarket;
98
99
100 public void init(String type, CampaignEventTarget eventTarget) {
101 super.init(type, eventTarget, false);
102 }
103
104 public void startEvent() {
105 super.startEvent(true);
106 if (market == null) return;
107
108 switch (market.getSize()) {
109 case 1:
110 case 2:
111 case 3:
112 messagePriority = MessagePriority.SYSTEM;
113 break;
114 case 4:
115 case 5:
116 messagePriority = MessagePriority.CLUSTER;
117 break;
118 case 6:
119 case 7:
120 case 8:
121 case 9:
122 messagePriority = MessagePriority.SECTOR;
123 break;
124 }
125
126 // moved to FoodShortage condition
127// String sellId = Stats.getPlayerSellImpactMultId(Commodities.FOOD);
128// market.getStats().getDynamic().getStat(sellId).modifyFlat(getId() + "_mod", getStabilityImpact());
129
130 baseFoodToMeetShortage = getBaseShortageAmount();
131 //foodToMeetShortage = baseFoodToMeetShortage;
132
133 maxDurationDays = 20f + (float) Math.random() * 20f;
134
135 daysBeforeReliefCheck = 7f + (float) Math.random() * 7f;
136 daysBeforeReliefSend = daysBeforeReliefCheck + (float) Math.random() * 7f;
137
138 foodShortageConditionToken = market.addCondition(Conditions.EVENT_FOOD_SHORTAGE, this);
140
141 preEventFoodLevel = com.getStockpile();
142 com.setStockpile(com.getStockpile() * getStockpileMult());
145
146
147 SubmarketAPI open = market.getSubmarket("open_market");
148 if (open != null) {
149 float food = open.getCargo().getQuantity(CargoItemType.RESOURCES, Commodities.FOOD);
150 open.getCargo().removeItems(CargoItemType.RESOURCES, Commodities.FOOD, food);
151 }
152
153 SubmarketAPI black = market.getSubmarket("black_market");
154 if (black != null) {
156 black.getCargo().addItems(CargoItemType.RESOURCES, Commodities.FOOD,
157 (int)Math.max(1, baseFoodToMeetShortage * (0.1f + (float) Math.random() * 0.05f)));
158 }
159
160 Global.getSector().reportEventStage(this, "start", messagePriority);
161
162 log.info(getLoggingId() + " Starting food shortage" +
163 ", food needed: " + (int) baseFoodToMeetShortage +
164 ", stockpile mult: " + getStockpileMult() +
165 ", max duration: " + (int) maxDurationDays + " days");
166 }
167
168
169 private float getBaseShortageAmount() {
170 float stockpileMult = getStockpileMult();
172 float amount = com.getStockpile() * (1f - stockpileMult);
173 if (amount < 50) amount = 50;
174 return Misc.getRounded(amount);
175 }
176
177
178 private float getStockpileMult() {
179 switch ((int) market.getSize()) {
180 case 0:
181 case 1:
182 return 0f;
183 case 2:
184 case 3:
185 return 0.2f;
186 case 4:
187 case 5:
188 return 0.3f;
189 case 6:
190 case 7:
191 return 0.5f;
192 case 8:
193 case 9:
194 return 0.9f;
195 }
196 return 1f;
197// switch ((int) market.getSize()) {
198// case 0:
199// case 1:
200// return 0f;
201// case 2:
202// case 3:
203// return 0.25f;
204// case 4:
205// case 5:
206// return 0.5f;
207// case 6:
208// case 7:
209// case 8:
210// case 9:
211// return 0.9f;
212// }
213// return 1f;
214 }
215
216
217 public float getStabilityImpact() {
218 switch ((int) market.getSize()) {
219 case 0:
220 case 1:
221 return 4;
222 case 2:
223 case 3:
224 return 3;
225 case 4:
226 case 5:
227 return 2;
228 case 6:
229 case 7:
230 case 8:
231 case 9:
232 return 1;
233 }
234 return 1f;
235 }
236
237 public float getReliefAbortUnrest() {
238 return 2;
239 }
240
241 public float getAddedExpiredUnrest() {
242 return 1;
243 }
244
245 public float getReducedEndedUnrest() {
246 return 1;
247 }
248
249 public float getEndBlackUnrest() {
250 float base = getStabilityImpact();
251 float mult = Math.min(1f, netDeliveredByPlayerBlack / baseFoodToMeetShortage);
252 return Math.round(base * mult);
253 }
254
255 public void advance(float amount) {
256 if (Global.getSector().isPaused()) return;
257
258 //float econInterval = Global.getSettings().getFloat("economyIntervalnGameDays");
259 float days = Global.getSector().getClock().convertToDays(amount);
260
261 if (!isEventStarted()) {
262 return;
263 }
264
265 if (isDone()) return;
266
267 elapsedDays += days;
268
269 if (elapsedDays > daysBeforeReliefCheck && stage == 0) {
270 stage++;
271
272 reliefMarket = findNearestMarket(market, new MarketFilter() {
273 public boolean acceptMarket(MarketAPI market) {
274 if (market == FoodShortageEvent.this.market) {
275 return false;
276 }
278 return false;
279 }
281 return false;
282 }
283 if (market.getCommodityData(Commodities.FOOD).getStockpile() < baseFoodToMeetShortage) {
284 return false;
285 }
286
289 if (ep.getProbability() > 0.1) {
290 return false;
291 }
292 if (manager.isOngoing(ep)) {
293 return false;
294 }
295 if ((float) Math.random() * 10f > market.getStabilityValue()) return false;
296
297 return market.getSize() >= FoodShortageEvent.this.market.getSize();
298 }
299 });
300 //reliefMarket = Global.getSector().getEconomy().getMarket("sindria");
301
302 //if ((float) Math.random() > 0.67f || market.getFaction().getId().equals("pirates")) {
303 if (market.getFaction().getId().equals("pirates")) {
304 reliefMarket = null;
305 }
306
307 if (reliefMarket != null) {
308 SharedData.getData().getMarketsThatSentRelief().add(reliefMarket.getId(), 14f + (float) Math.random() * 14f);
309 Global.getSector().reportEventStage(this, "warning_relief", reliefMarket.getPrimaryEntity(), messagePriority);
310 } else {
311 log.info(getLoggingId() + " No relief market found");
312 applyReliefFleetDidNotMakeItConsequences();
313 Global.getSector().reportEventStage(this, "relief_unavailable", messagePriority);
314 }
315 }
316
317 if (elapsedDays > daysBeforeReliefSend && stage == 1) {
318 stage++;
319 if (reliefMarket != null) {
320 createReliefFleet();
321 if (reliefFleet == null) {
322 log.info(getLoggingId() + " Failed to spawn relief fleet");
323 applyReliefFleetDidNotMakeItConsequences();
324 Global.getSector().reportEventStage(this, "relief_unavailable", messagePriority);
325 } else {
326 originalReliefFleetPoints = reliefFleet.getFleetPoints();
327
329 reliefMarket.getPrimaryEntity().getContainingLocation().addEntity(reliefFleet);
330 reliefFleet.setLocation(entity.getLocation().x, entity.getLocation().y);
331
332 reliefFleet.addAssignment(FleetAssignment.ORBIT_PASSIVE, reliefMarket.getPrimaryEntity(), 2,
333 "loading food from " + reliefMarket.getName(), new Script() {
334 public void run() {
335 reliefFleet.getCargo().addItems(CargoItemType.RESOURCES, Commodities.FOOD,
336 reliefFleet.getCargo().getMaxCapacity() * (1f - FleetFactory.SUPPLIES_FRACTION));
337 }
338 });
340 "delivering food relief from " + reliefMarket.getName() + " to " + market.getName());
342 "offloading food at " + market.getName(), new Script() {
343 public void run() {
344 endEvent(Ending.RELIEF_ARRIVED);
345 }
346 });
348 "returning to " + reliefMarket.getName() + " after delivering food relief to " + market.getName());
349
350 Global.getSector().reportEventStage(this, "relief_sent", reliefMarket.getPrimaryEntity(), messagePriority);
351 log.info(getLoggingId() + " Sending relief fleet from " + reliefMarket.getName());
352 }
353 }
354 }
355
356 if (reliefFleet != null) {
357 float currPoints = reliefFleet.getFleetPoints();
358 if (currPoints < originalReliefFleetPoints * 0.5f) {
359 Global.getSector().reportEventStage(this, "relief_aborted", reliefMarket.getPrimaryEntity(), messagePriority);
360 log.info(getLoggingId() + " Relief aborted, fleet returning to " + reliefMarket.getName());
361
362 reliefFleet.clearAssignments();
364 applyReliefFleetDidNotMakeItConsequences();
365 reliefFleet = null;
366 }
367 }
368
369 if ((elapsedDays > maxDurationDays || elapsedDays > MAX_POSSIBLE_DURATION) && stage == 2) {
370 endEvent(Ending.DURATION_EXPIRED);
371 stage++;
372 }
373 }
374
375
376 private void applyReliefFleetDidNotMakeItConsequences() {
377 float abortUnrest = getReliefAbortUnrest();
378 increaseRecentUnrest((int) abortUnrest);
379 log.info(" +" + abortUnrest + " unrest at " + market.getName());
380 }
381
382 private void createReliefFleet() {
383 reliefFleet = FleetFactory.createEmptyFleet(reliefMarket.getFactionId(), FleetTypes.FOOD_RELIEF_FLEET, reliefMarket);
384
385 int size = market.getSize();
386 float combat = size;
387 float freighter = size * 1.5f;
388 float transport = size * 0.25f;
389 combat *= 5;
390 freighter *= 3;
391 transport *= 3;
392 reliefFleet = FleetFactoryV3.createFleet(new FleetParamsV3(
393 reliefMarket,
395 combat, // combatPts
396 freighter, // freighterPts
397 0f, // tankerPts
398 transport, // transportPts
399 0f, // linerPts
400 0f, // utilityPts
401 0f // qualityMod
402 ));
403 }
404
405
406
407 private void endEvent(Ending ending) {
408 if (market != null) {
410 }
411 ended = true;
412 CommodityOnMarketAPI com = market.getCommodityData(Commodities.FOOD);
413 com.setStockpile(com.getStockpile() / getStockpileMult());
414 com.getPlayerSupplyPriceMod().unmodifyMult(PRICE_MOD_ID);
415 com.getPlayerSupplyPriceMod().unmodifyFlat(PRICE_MOD_ID);
416
417 // moved to FoodShortage condition
418// String sellId = Stats.getPlayerSellImpactMultId(Commodities.FOOD);
419// market.getStats().getDynamic().getStat(sellId).unmodify(getId() + "_mod");
420
421 float ongoingStabilityImpact = getStabilityImpact();
422
423 Misc.unsetAll("$market.foodShortage", MemKeys.MARKET, market.getMemoryWithoutUpdate());
424 final InteractionDialogAPI dialog = Global.getSector().getCampaignUI().getCurrentInteractionDialog();
425 switch (ending) {
426 case DURATION_EXPIRED:
427 Global.getSector().reportEventStage(this, "end_expired", messagePriority);
428 log.info(getLoggingId() + " Expired");
429 ongoingStabilityImpact += getAddedExpiredUnrest();
430 market.getMemoryWithoutUpdate().set("$foodShortageExpired", true, 10);
431 break;
432 case PLAYER_ENDED:
433 if (dialog != null && dialog.getPlugin().getMemoryMap() != null && dialog.getTextPanel() != null) {
434 dialog.getTextPanel().addParagraph("Financial transaction confirmed", Global.getSettings().getColor("buttonText"));
435 }
436 if (elapsedDays < 7) {
437 ongoingStabilityImpact = 0;
438 Global.getSector().reportEventStage(this, "end_player_fast", null, MessagePriority.DELIVER_IMMEDIATELY,
439 new BaseOnMessageDeliveryScript() {
440 public void beforeDelivery(CommMessageAPI message) {
441 Global.getSector().adjustPlayerReputation(
442 new RepActionEnvelope(RepActions.FOOD_SHORTAGE_PLAYER_ENDED_FAST, market, message,
443 dialog.getTextPanel(), true),
445 }
446 });
447 log.info(getLoggingId() + " Ended by player within 7 days");
448 market.getMemoryWithoutUpdate().set("$foodShortageEndedByPlayerFast", true, 10);
449 //market.getFaction().adjustRelationship(Factions.PLAYER, RepRewards.HIGH);
450// Global.getSector().adjustPlayerReputation(
451// new RepActionEnvelope(RepActions.FOOD_SHORTAGE_PLAYER_ENDED_FAST, market),
452// market.getFaction().getId());
453 } else {
454 ongoingStabilityImpact = Math.max(0, ongoingStabilityImpact - getReducedEndedUnrest());
455 Global.getSector().reportEventStage(this, "end_player", null, MessagePriority.DELIVER_IMMEDIATELY,
456 new BaseOnMessageDeliveryScript() {
457 public void beforeDelivery(CommMessageAPI message) {
458 Global.getSector().adjustPlayerReputation(
459 new RepActionEnvelope(RepActions.FOOD_SHORTAGE_PLAYER_ENDED_NORMAL, market, message,
460 dialog.getTextPanel(), true),
462 }
463 });
464 log.info(getLoggingId() + " Ended by player");
465 market.getMemoryWithoutUpdate().set("$foodShortageEndedByPlayer", true, 10);
466 }
467 if (dialog != null && dialog.getPlugin().getMemoryMap() != null) {
468 dialog.getVisualPanel().hideCore();
469 FireBest.fire(null, dialog, dialog.getPlugin().getMemoryMap(), "FoodShortageEndedByPlayerSale");
470 }
471 break;
472 case PLAYER_ENDED_BLACK:
473 if (dialog != null && dialog.getPlugin().getMemoryMap() != null && dialog.getTextPanel() != null) {
474 dialog.getTextPanel().addParagraph("Financial transaction confirmed", Global.getSettings().getColor("buttonText"));
475 }
476 ongoingStabilityImpact = ongoingStabilityImpact + getEndBlackUnrest();
477 Global.getSector().reportEventStage(this, "end_player_black", null, MessagePriority.DELIVER_IMMEDIATELY,
478 new BaseOnMessageDeliveryScript() {
479 public void beforeDelivery(CommMessageAPI message) {
480// Global.getSector().adjustPlayerReputation(
481// new RepActionEnvelope(RepActions.FOOD_SHORTAGE_PLAYER_ENDED_MEDIUM_CONTRIB, market, message,
482// dialog.getTextPanel(), true),
483// market.getFaction().getId());
484 }
485 });
486 log.info(getLoggingId() + " Ended by player black market trade");
487 market.getMemoryWithoutUpdate().set("$foodShortageEndedByPlayerBlack", true, 10);
488 if (dialog != null && dialog.getPlugin().getMemoryMap() != null) {
489 dialog.getVisualPanel().hideCore();
490 FireBest.fire(null, dialog, dialog.getPlugin().getMemoryMap(), "FoodShortageEndedByPlayerSale");
491 }
492 break;
493 case RELIEF_ARRIVED:
494 Global.getSector().reportEventStage(this, "end_relief_arrived", null, messagePriority);
495 ongoingStabilityImpact = Math.max(0, ongoingStabilityImpact - getReducedEndedUnrest());
496 log.info(getLoggingId() + " Ended by relief fleet arrival");
497 market.getMemoryWithoutUpdate().set("$foodShortageEndedByNPC", true, 10);
498 break;
499 }
500
501 for (SubmarketAPI sub : market.getSubmarketsCopy()) {
502 if (sub.getPlugin().isFreeTransfer()) continue;
503
504 float food = sub.getCargo().getQuantity(CargoItemType.RESOURCES, Commodities.FOOD);
505 sub.getCargo().removeItems(CargoItemType.RESOURCES, Commodities.FOOD, food);
506 }
507
508 increaseRecentUnrest((int) ongoingStabilityImpact);
509 log.info(getLoggingId() + " Unrest +" + (int)ongoingStabilityImpact);
510
511 }
512
513 public boolean isDone() {
514 return ended;
515 }
516
518 return messagePriority;
519 }
520
522 return messagePriority;
523 }
524
525 public String getStageIdForLikely() {
526 return "likely";
527 }
528
529 public String getStageIdForPossible() {
530 return "possible";
531 }
532
533
534// private float updatePurchaseListAndReturnTotalBought() {
535// CampaignClockAPI clock = Global.getSector().getClock();
536// float maxDays = 30f;
537// float total = 0f;
538// List<PlayerFoodTransaction> remove = new ArrayList<PlayerFoodTransaction>();
539// for (PlayerFoodTransaction p : preEventTransactions) {
540// float elapsed = clock.getElapsedDaysSince(p.timestamp);
541// if (elapsed > maxDays) {
542// remove.add(p);
543// } else {
544// total += p.quantity;
545// }
546// }
547// preEventTransactions.removeAll(remove);
548//
549// return total;
550// }
551
552 @Override
554 if (!isEventStarted()) return;
555
556 if (market == null) return;
557 if (transaction.getMarket() != market) return;
558 if (isDone()) return;
559
560// if (market.getId().equals("jangala")) {
561// System.out.println("123sfe");
562// }
563
564 SubmarketPlugin plugin = transaction.getSubmarket().getPlugin();
565 if (!plugin.isParticipatesInEconomy()) return;
566
567 float bought = transaction.getQuantityBought(Commodities.FOOD);
568 float sold = transaction.getQuantitySold(Commodities.FOOD);
569 float netBought = bought - sold;
570
571 if (netBought == 0) return;
572
573// CampaignEventManagerAPI manager = Global.getSector().getEventManager();
574// EventProbabilityAPI ep = manager.getProbability(getEventType(), getEventTarget());
575
576
578 float postTransactionLevel = com.getStockpile();
579
580 if (plugin.isBlackMarket()) {
581 netDeliveredByPlayerBlack -= bought;
582 netDeliveredByPlayerBlack += sold;
583 } else {
584 netDeliveredByPlayerOther -= bought;
585 netDeliveredByPlayerOther += sold;
586 }
587
588 if (postTransactionLevel >= preEventFoodLevel &&
589 netDeliveredByPlayerOther + netDeliveredByPlayerBlack >= MIN_FRACTION_FOR_PLAYER_ENDING_EVENT * baseFoodToMeetShortage) {
590 if (netDeliveredByPlayerBlack >= MIN_FRACTION_FOR_PLAYER_ENDING_EVENT * baseFoodToMeetShortage) {
591 endEvent(Ending.PLAYER_ENDED_BLACK);
592 } else {
593 endEvent(Ending.PLAYER_ENDED);
594 }
595 // added in endEvent() before rep gain
596// InteractionDialogAPI dialog = Global.getSector().getCampaignUI().getCurrentInteractionDialog();
597// if (dialog != null && dialog.getPlugin().getMemoryMap() != null) {
598// //dialog.getTextPanel().clear();
599// //dialog.getTextPanel().addParagraph("Financial transaction confirmed", Global.getSettings().getColor("buttonText"));
600// dialog.getVisualPanel().hideCore();
601// FireBest.fire(null, dialog, dialog.getPlugin().getMemoryMap(), "FoodShortageEndedByPlayerSale");
602// }
603 }
604 }
605
606 @Override
607 public void reportFleetDespawned(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
608 if (fleet == reliefFleet) {
609 Global.getSector().reportEventStage(this, "relief_lost", reliefMarket.getPrimaryEntity(), messagePriority);
610 applyReliefFleetDidNotMakeItConsequences();
611 reliefFleet = null;
612 }
613 }
614
616 return Math.max(0, baseFoodToMeetShortage - netDeliveredByPlayerBlack - netDeliveredByPlayerOther);
617 }
618
619 public Map<String, String> getTokenReplacements() {
620 Map<String, String> map = super.getTokenReplacements();
621
622 /*
623 $targetFaction
624 $reliefSystem
625 $reliefEntity
626 $playerName
627 */
628 map.put("$targetFaction", eventTarget.getEntity().getFaction().getDisplayName());
629
630 if (reliefMarket != null) {
631 SectorEntityToken primary = reliefMarket.getPrimaryEntity();
632 LocationAPI loc = primary.getContainingLocation();
633 if (loc instanceof StarSystemAPI) {
634 //map.put("$reliefSystem", ((StarSystemAPI)loc).getBaseName() + " star system");
635 map.put("$reliefSystem", ((StarSystemAPI)loc).getBaseName());
636 } else {
637 map.put("$reliefSystem", "hyperspace");
638 }
639
640 map.put("$reliefMarket", primary.getName());
641// map.put("$reliefSystem", "Askonia");
642// map.put("$reliefEntity", "Volturn");
643 if (reliefFleet != null) {
645 float eta = dist / reliefFleet.getFleetData().getTravelSpeed();
646 // since travel speed is units/second, not per day
648 eta += 2f;
649
650 String s = null;
651 if (eta <= 3f) {
652 s = "within a few days";
653 } else if (eta <= 7) {
654 s = "within a week";
655 } else if (eta <= 14) {
656 s = "within a couple of weeks";
657 } else if (eta <= 30) {
658 s = "within a month";
659 } else {
660 s = "in the coming months";
661 }
662 map.put("$eta", s);
663 }
664 }
665
666 int needed = (int) Misc.getRounded(getRemainingFoodToMeetShortage());
667 map.put("$neededFood", "" + needed);
668
669 map.put("$stabilityPenalty", "" + (int) getStabilityImpact());
670 map.put("$stabilityPenaltyRelief", "" + (int) getReliefAbortUnrest());
671 map.put("$stabilityPenaltyExpire", "" + (int) (getAddedExpiredUnrest() + getStabilityImpact()));
672 map.put("$stabilityPenaltyEnd", "" + (int) Math.max(0, getStabilityImpact() - getReducedEndedUnrest()));
673 map.put("$stabilityPenaltyEndBlack", "" + (int) (getStabilityImpact() + getEndBlackUnrest()));
674 return map;
675 }
676
677 @Override
678 public String[] getHighlights(String stageId) {
679 List<String> result = new ArrayList<String>();
680 if ("start".equals(stageId)) {
681 addTokensToList(result, "$stabilityPenalty", "$neededFood");
682 }
683 if ("relief_unavailable".equals(stageId)) {
684 addTokensToList(result, "$stabilityPenaltyRelief");
685 }
686 if ("relief_aborted".equals(stageId)) {
687 addTokensToList(result, "$stabilityPenaltyRelief");
688 }
689 if ("relief_lost".equals(stageId)) {
690 addTokensToList(result, "$stabilityPenaltyRelief");
691 }
692 if ("end_relief_arrived".equals(stageId)) {
693 addTokensToList(result, "$stabilityPenaltyEnd");
694 }
695 if ("end_expired".equals(stageId)) {
696 addTokensToList(result, "$stabilityPenaltyExpire");
697 }
698 if ("end_player".equals(stageId)) {
699 addTokensToList(result, "$stabilityPenaltyEnd");
700 }
701 if ("end_player_black".equals(stageId)) {
702 addTokensToList(result, "$stabilityPenaltyEndBlack");
703 }
704 if ("end_player_fast".equals(stageId)) {
705 }
706 return result.toArray(new String[0]);
707 }
708
709 @Override
710 public Color[] getHighlightColors(String stageId) {
711 return super.getHighlightColors(stageId);
712// String [] highlights = getHighlights(stageId);
713// if (highlights != null) {
714// Color c = Global.getSettings().getColor("buttonShortcut");
715// Color [] colors = new Color[highlights.length];
716// Arrays.fill(colors, c);
717// return colors;
718// }
719// //return null;
720// return null;
721 }
722
723 @Override
724 public List<String> getRelatedCommodities() {
725 List<String> commodities = new ArrayList<String>();
726 commodities.add(Commodities.FOOD);
727 return commodities;
728 }
729
730 @Override
731 public List<PriceUpdatePlugin> getPriceUpdates() {
732 List<PriceUpdatePlugin> updates = new ArrayList<PriceUpdatePlugin>();
734 return updates;
735 }
736
737 public String getEventName() {
738 if (!isEventStarted()) {
739 return "Possible food shortage - " + market.getName() + "";
740 }
741 if (isDone()) {
742 return "Food shortage - " + market.getName() + " (over)";
743 }
744 return "Food shortage - " + market.getName() + "";
745 }
746}
747
748
749
750
static SettingsAPI getSettings()
Definition Global.java:57
static Logger getLogger(Class c)
Definition Global.java:32
static SectorAPI getSector()
Definition Global.java:65
void modifyMult(String source, float value)
void modifyFlat(String source, float value)
void addTokensToList(List< String > list, String ... keys)
static MarketAPI findNearestMarket(MarketAPI from, MarketFilter filter)
void reportFleetDespawned(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
void init(String type, CampaignEventTarget eventTarget)
void reportPlayerMarketTransaction(PlayerMarketTransaction transaction)
static CampaignFleetAPI createFleet(FleetParamsV3 params)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
Definition Misc.java:599
static float getRounded(float in)
Definition Misc.java:639
void addAssignment(FleetAssignment assignment, SectorEntityToken target, float maxDurationInDays)
InteractionDialogAPI getCurrentInteractionDialog()
float getQuantity(CargoAPI.CargoItemType type, Object data)
boolean removeItems(CargoAPI.CargoItemType itemType, Object data, float quantity)
void addItems(CargoAPI.CargoItemType itemType, Object data, float quantity)
boolean isHostileTo(FactionAPI other)
void addEntity(SectorEntityToken entity)
CampaignEventManagerAPI getEventManager()
void reportEventStage(CampaignEventPlugin event, String stage, MessagePriority priority)
CommodityOnMarketAPI getCommodityData(String commodityId)
SubmarketAPI getSubmarket(String specId)
EventProbabilityAPI getProbability(String eventType, SectorEntityToken eventTargetEntity)
void set(String key, Object value)