Starsector API
Loading...
Searching...
No Matches
ProcurementMissionIntel.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.Map;
6import java.util.Set;
7
8import org.apache.log4j.Logger;
9
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.CargoAPI;
13import com.fs.starfarer.api.campaign.CargoStackAPI;
14import com.fs.starfarer.api.campaign.FactionAPI;
15import com.fs.starfarer.api.campaign.InteractionDialogAPI;
16import com.fs.starfarer.api.campaign.RepLevel;
17import com.fs.starfarer.api.campaign.SectorEntityToken;
18import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
19import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
20import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
21import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
22import com.fs.starfarer.api.campaign.econ.EconomyAPI;
23import com.fs.starfarer.api.campaign.econ.MarketAPI;
24import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
25import com.fs.starfarer.api.campaign.rules.MemoryAPI;
26import com.fs.starfarer.api.characters.ImportantPeopleAPI;
27import com.fs.starfarer.api.characters.PersonAPI;
28import com.fs.starfarer.api.characters.ImportantPeopleAPI.PersonDataAPI;
29import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
30import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.MissionCompletionRep;
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.econ.impl.BaseIndustry;
34import com.fs.starfarer.api.impl.campaign.ids.Commodities;
35import com.fs.starfarer.api.impl.campaign.ids.Factions;
36import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
37import com.fs.starfarer.api.impl.campaign.ids.Ranks;
38import com.fs.starfarer.api.impl.campaign.ids.Tags;
39import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
40import com.fs.starfarer.api.impl.campaign.shared.PlayerTradeDataForSubmarket;
41import com.fs.starfarer.api.impl.campaign.shared.SharedData;
42import com.fs.starfarer.api.ui.ButtonAPI;
43import com.fs.starfarer.api.ui.IntelUIAPI;
44import com.fs.starfarer.api.ui.LabelAPI;
45import com.fs.starfarer.api.ui.SectorMapAPI;
46import com.fs.starfarer.api.ui.TooltipMakerAPI;
47import com.fs.starfarer.api.util.Misc;
48import com.fs.starfarer.api.util.WeightedRandomPicker;
49import com.fs.starfarer.api.util.Misc.Token;
50
51
53 public static final String PERSON_CHECKOUT_REASON = "MPM_mission_contact";
54 //public static final Float POSTING_RANGE_LY = 0f;
55
56 public static String BUTTON_COMMODITY_INFO = "Show commodity info";
57
58 public static Logger log = Global.getLogger(ProcurementMissionIntel.class);
59
60 protected MarketAPI market;
61 protected PersonAPI contact;
62 protected float quantity;
63 protected float pricePerUnit;
64
65 protected boolean contactWillInitiateComms = false;
66 protected CommodityOnMarketAPI commodity;
67
68 protected float baseReward;
69
71 String commodityId = pickCommodity();
72 if (commodityId == null) {
73 endMission();
75 return;
76 }
77
78 quantity = getQuantity(commodityId);
79 float illegalMult = 0.2f;
80 float min = 10f;
81 market = pickMarket(commodityId, quantity, illegalMult, min);
82 if (market == null) {
83 endMission();
85 return;
86 }
87
88 commodity = market.getCommodityData(commodityId);
89
90// commodityId = Commodities.ORE;
91// market = Global.getSector().getEconomy().getMarket("sphinx");
92 quantity = (int) getQuantityAdjustedForMarket(commodityId, quantity, illegalMult, min, market);
93
94 if (quantity <= 0) {
95 endMission();
97 return;
98 }
99
100 WeightedRandomPicker<Float> durationPicker = new WeightedRandomPicker<Float>();
101 durationPicker.add(20f);
102 durationPicker.add(30f);
103 durationPicker.add(40f);
104 durationPicker.add(60f);
105
106 setDuration(durationPicker.pick());
107
108 baseReward = market.getDemandPrice(commodityId, quantity, false);
109
110 float minReward = 7500 + (float) Math.random() * 5000f;
111 if (baseReward < minReward) {
112 quantity = quantity * (minReward / baseReward);
113 if (quantity > 5000) quantity = 5000;
114 quantity = (int)(((int)quantity / 10) * 10);
115 if (quantity <= 0) {
116 endMission();
118 return;
119 }
120 baseReward = market.getDemandPrice(commodityId, quantity, false);
121 }
122
123 float basePerUnit = market.getCommodityData(commodityId).getCommodity().getBasePrice();
124 if (baseReward < basePerUnit * quantity) baseReward = basePerUnit * quantity;
125
126 float maxQuantity = 10000f;
127 float maxDuration = 60f;
128
129 float durationBonus = Math.min(baseReward/quantity * (0.5f * (2f - Math.min(1f, duration / maxDuration))), 300);
130 float quantityBonus = Math.min(baseReward/quantity * (0.5f * (2f - Math.min(1f, quantity / maxQuantity))), 300);
131 if (durationBonus < 10) durationBonus = 10;
132 if (quantityBonus < 10) quantityBonus = 10;
133
134 //baseReward += durationBonus * quantity;
135 //baseReward += quantityBonus * quantity;
136
137 contact = pickContact(market, market.getCommodityData(commodityId));
138 Global.getSector().getImportantPeople().checkOutPerson(contact, PERSON_CHECKOUT_REASON);
139
140 boolean illegal = contact.getFaction().isHostileTo(market.getFaction());
141
142 if (illegal) {
143 baseReward *= 3f;
144 } else {
145 baseReward *= 2f;
146 }
147
148
149 pricePerUnit = (int) (baseReward / quantity);
150
151// if (commodityId.equals("drugs")) {
152// System.out.println("sdflhwefwe");
153// }
154 if (pricePerUnit < 10) pricePerUnit = 10;
155
156
157 log.info("Created ProcurementMissionIntel: " + commodityId + " to " + market.getName());
158
160 setPostingLocation(market.getPrimaryEntity());
161
162 Global.getSector().getIntelManager().queueIntel(this);
163 }
164
165 public void missionAccepted() {
166 market.getCommDirectory().addPerson(contact);
167
168 contact.getMemoryWithoutUpdate().set("$mpm_isPlayerContact", true, duration);
169 contact.getMemoryWithoutUpdate().set("$mpm_eventRef", this, duration);
170 contact.getMemoryWithoutUpdate().set("$mpm_commodityName", commodity.getCommodity().getName().toLowerCase(), duration);
171 contact.getMemoryWithoutUpdate().set("$mpm_quantity", Misc.getWithDGS((int)quantity), duration);
172 Misc.setFlagWithReason(contact.getMemoryWithoutUpdate(),
173 MemFlags.MEMORY_KEY_REQUIRES_DISCRETION, "mpm_" + commodity.getId(),
174 true, duration);
175
176 Misc.setFlagWithReason(contact.getMemoryWithoutUpdate(),
177 MemFlags.MEMORY_KEY_MISSION_IMPORTANT,
178 "mpm", true, duration);
179
180 contactWillInitiateComms = (float) Math.random() > 0.5f;
181
182 boolean illegal = contact.getFaction().isHostileTo(market.getFaction());
183 if (illegal) {
185 }
186
188 contact.incrWantsToContactReasons();
189 }
190
191 }
192
193
194 protected PersonAPI pickContact(MarketAPI market, CommodityOnMarketAPI com) {
195 Global.getSettings().profilerBegin(this.getClass().getSimpleName() + ".pickContact()");
196 PersonAPI contact = null;
197 ImportantPeopleAPI ip = Global.getSector().getImportantPeople();
198
199 String comId = com.getId();
200
201 if (market.getFaction().isPlayerFaction()) {
202 contact = getCriminal(market, PERSON_CHECKOUT_REASON, Factions.PIRATES).getPerson();
203 }
204
205 if (contact == null && com.getCommodity().hasTag(Commodities.TAG_MILITARY)) {
206 if ((float) Math.random() > 0.1f) {
207 contact = ip.getPerson(market.getFaction(), market,
208 PERSON_CHECKOUT_REASON, Ranks.GROUND_LIEUTENANT,
209 Ranks.POST_SUPPLY_OFFICER,
210 Ranks.POST_BASE_COMMANDER,
211 Ranks.POST_OUTPOST_COMMANDER,
212 Ranks.POST_PORTMASTER).getPerson();
213 } else {
214 contact = getCriminal(market, PERSON_CHECKOUT_REASON, Factions.PIRATES).getPerson();
215 }
216 }
217
218 if (contact == null && com.getCommodity().hasTag(Commodities.TAG_MEDICAL)) {
219 if ((float) Math.random() > 0.25f) {
220 contact = ip.getPerson((float) Math.random() > 0.5f ? Factions.INDEPENDENT : market.getFactionId(),
221 market,
222 PERSON_CHECKOUT_REASON, Ranks.CITIZEN,
223 Ranks.POST_MEDICAL_SUPPLIER).getPerson();
224 } else {
225 contact = getCriminal(market, PERSON_CHECKOUT_REASON, Factions.PIRATES).getPerson();
226 }
227 }
228
229 if (contact == null && com.getCommodity().hasTag(Commodities.TAG_LUXURY)) {
230 if ((float) Math.random() > 0.1f && !market.isIllegal(comId)) {
231 contact = getLegitTrader(market, PERSON_CHECKOUT_REASON, market.getFactionId()).getPerson();
232 } else {
233 contact = getCriminal(market, PERSON_CHECKOUT_REASON, Factions.PIRATES).getPerson();
234 }
235 }
236
237 if (contact == null) {
238 if ((float) Math.random() > 0.05f && !market.isIllegal(comId)) {
239 contact = getLegitTrader(market, PERSON_CHECKOUT_REASON, market.getFactionId()).getPerson();
240 } else {
241 contact = getCriminal(market, PERSON_CHECKOUT_REASON, Factions.PIRATES).getPerson();
242 }
243 }
244
245 if (contact == null) {
246 // shouldn't happen, but just in case
247 contact = market.getFaction().createRandomPerson();
248 contact.setPostId(Ranks.POST_CITIZEN);
249 contact.setRankId(null);
250 market.addPerson(contact);
251 ip.addPerson(contact);
252 ip.getData(contact).getLocation().setMarket(market);
253 }
255 return contact;
256 }
257
258
259 public static PersonDataAPI getLegitTrader(MarketAPI market, String checkoutReason, String factionId) {
260 ImportantPeopleAPI ip = Global.getSector().getImportantPeople();
261 return ip.getPerson(factionId,
262 market,
263 checkoutReason, Ranks.CITIZEN,
264 Ranks.POST_MERCHANT,
265 Ranks.POST_COMMODITIES_AGENT,
266 Ranks.POST_INVESTOR,
267 Ranks.POST_TRADER);
268 }
269
270 public static PersonDataAPI getCriminal(MarketAPI market, String checkoutReason, String factionId) {
271 ImportantPeopleAPI ip = Global.getSector().getImportantPeople();
272 return ip.getPerson(factionId,
273 market,
274 checkoutReason, Ranks.CITIZEN,
275 Ranks.POST_GANGSTER,
276 Ranks.POST_SMUGGLER,
277 Ranks.POST_FENCE);
278 }
279
280
281
282
283 protected String pickCommodity() {
284 Global.getSettings().profilerBegin(this.getClass().getSimpleName() + ".pickCommodity()");
285 EconomyAPI economy = Global.getSector().getEconomy();
286 WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>();
287
288 for (String curr : economy.getAllCommodityIds()) {
289 CommoditySpecAPI spec = economy.getCommoditySpec(curr);
290 if (spec.isMeta()) continue;
291 if (spec.hasTag(Commodities.TAG_CREW)) continue;
292 if (spec.hasTag(Commodities.TAG_MARINES)) continue;
293 if (spec.hasTag(Commodities.TAG_NON_ECONOMIC)) continue;
294// if (spec.getId().equals(Commodities.SUPPLIES)) continue;
295// if (spec.getId().equals(Commodities.FUEL)) continue;
296
297 //float weight = spec.getBasePrice();
298 float weight = 1f;
299 picker.add(curr, weight);
300 }
302 return picker.pick();
303 }
304
305 protected int getQuantity(String commodityId) {
306 CommoditySpecAPI spec = Global.getSettings().getCommoditySpec(commodityId);
307 float cargoCapacity = 30;
308 CampaignFleetAPI player = Global.getSector().getPlayerFleet();
309 if (player != null) {
310 if (Commodities.FUEL.equals(commodityId)) {
311 cargoCapacity = Math.max(cargoCapacity, cargoCapacity = player.getCargo().getMaxFuel());
312 } else {
313 cargoCapacity = Math.max(cargoCapacity, player.getCargo().getMaxCapacity());
314 }
315 }
316
317 // using fuel as a mid-price commodity
318 CommoditySpecAPI fuel = Global.getSettings().getCommoditySpec(Commodities.FUEL);
319 float targetValue = cargoCapacity * Math.max(5f, fuel.getBasePrice());
320
321 float units = targetValue / Math.max(5f, spec.getBasePrice());
322
323 units *= 0.5f + (float) Math.random();
324
325 //return (int) Misc.getRounded(units);
326 return (int) units / 10 * 10;
327 }
328
329 protected float getQuantityAdjustedForMarket(String commodityId, float quantity, float illegalMult, float min, MarketAPI market) {
330 if (market.getSize() <= 4) {
331 quantity = Math.min(quantity, 200);
332 } else if (market.getSize() == 5) {
333 quantity = Math.min(quantity, 500);
334 } else if (market.getSize() == 6) {
335 quantity = Math.min(quantity, 1000);
336 } else if (market.getSize() == 7) {
337 quantity = Math.min(quantity, 2000);
338 } else if (market.getSize() >= 8) {
339 quantity = Math.min(quantity, 10000);
340 }
341 CommodityOnMarketAPI com = market.getCommodityData(commodityId);
342 if (com.getUtilityOnMarket() > 0) {
343 quantity /= com.getUtilityOnMarket();
344 }
345 boolean illegal = market.isIllegal(commodityId);
346 if (illegal) {
347 quantity *= illegalMult;
348 if (quantity < min) quantity = min;
349 }
350 return (int)quantity;
351 }
352
353 protected MarketAPI pickMarket(String commodityId, float quantity, float illegalMult, float min) {
354// if (true) {
355// return Global.getSector().getEconomy().getMarket("jangala");
356// }
357 Global.getSettings().profilerBegin(this.getClass().getSimpleName() + ".pickMarket()");
358 EconomyAPI economy = Global.getSector().getEconomy();
359
360 WeightedRandomPicker<MarketAPI> picker = new WeightedRandomPicker<MarketAPI>();
361
362 for (MarketAPI market : economy.getMarketsCopy()) {
363 if (market.isHidden()) continue;
364 if (market.isPlayerOwned()) continue;
365
366 //CommodityOnMarketAPI com = market.getCommodityData(commodityId);
367
368 boolean illegal = market.isIllegal(commodityId);
369 float test = getQuantityAdjustedForMarket(commodityId, quantity, illegalMult, min, market);
370 if (illegal) {
371 test *= illegalMult;
372 if (test < min) test = min;
373 }
374 //if (com.getAverageStockpileAfterDemand() >= minQty) continue;
375 // don't filter on demand - open up more possibilities; may be needed for non-market-condition reasons
376 //if (com.getDemand().getDemandValue() < minQty) continue;
377
378 if (doNearbyMarketsHave(market, commodityId, test * 0.5f)) continue;
379
380 float weight = market.getSize();
381
382 if (market.getFaction().isPlayerFaction()) {
383 weight *= 0.1f;
384 }
385
386 picker.add(market, weight);
387 }
389 return picker.pick();
390 }
391
392 protected boolean doNearbyMarketsHave(MarketAPI from, String commodityId, float minQty) {
393 if (from.getContainingLocation() == null) return false;
394 //if (from.getContainingLocation() == null || from.getContainingLocation().isHyperspace()) return false;
395
396 //Global.getSettings().profilerBegin(this.getClass().getSimpleName() + ".doNearbyMarketsHave()");
397 for (MarketAPI curr : Misc.getMarketsInLocation(from.getContainingLocation())) {
398 //if (curr == from) continue;
399 if (curr.getPrimaryEntity() != null && from.getPrimaryEntity() != null) {
400 float dist = Misc.getDistance(curr.getPrimaryEntity().getLocation(), from.getPrimaryEntity().getLocation());
401 if (dist > 10000) continue;
402 }
403
404 CommodityOnMarketAPI com = curr.getCommodityData(commodityId);
405 //if (com.getAvailable() >= 2 && com.getAvailable() >= com.getMaxDemand() - 1) return true;
406
407 int a = com.getAvailable();
408 if (a <= 0) continue;
409
410 float limit = BaseIndustry.getSizeMult(a);
411 limit *= com.getCommodity().getEconUnit();
412
413 if (limit * 0.5f >= minQty) return true;
414
415// if (com.getAboveDemandStockpile() >= minQty) {
416// //Global.getSettings().profilerEnd();
417// return true;
418// }
419
420 //if (com.getSupplyValue() >= minQty) return true;
421 for (SubmarketAPI submarket : curr.getSubmarketsCopy()) {
422 if (!submarket.getPlugin().isParticipatesInEconomy()) continue;
423 CargoAPI cargo = submarket.getCargoNullOk();
424 if (cargo == null) continue;
425 if (cargo.getQuantity(CargoItemType.RESOURCES, commodityId) >= minQty * 0.5f) return true;
426 }
427 }
428 //Global.getSettings().profilerEnd();
429 return false;
430 }
431
432
433
434
435
436 @Override
437 public void advanceMission(float amount) {
438 if (!market.isInEconomy()) {
439 setMissionResult(new MissionResult(0, null, null));
440 setMissionState(MissionState.FAILED);
441 endMission();
442 }
443 }
444
445
446 @Override
447 public boolean callEvent(String ruleId, final InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
448 String action = params.get(0).getString(memoryMap);
449
450 CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
451 CargoAPI cargo = playerFleet.getCargo();
452
453 String commodityId = commodity.getId();
454 if (action.equals("performDelivery")) {
455 cargo.removeItems(CargoItemType.RESOURCES, commodityId, quantity);
456 int reward = (int) baseReward;
457 cargo.getCredits().add(reward);
458
459 AddRemoveCommodity.addCommodityLossText(commodityId, (int) quantity, dialog.getTextPanel());
460 AddRemoveCommodity.addCreditsGainText(reward, dialog.getTextPanel());
461
462 applyTradeValueImpact(reward);
463
464 float repAmount = 0.01f * baseReward / 100000f;
465 if (repAmount < 0.01f) repAmount = 0.01f;
466 if (repAmount > 0.05f) repAmount = 0.05f;
467
468 MissionCompletionRep completionRep = new MissionCompletionRep(repAmount, RepLevel.WELCOMING, -repAmount, RepLevel.INHOSPITABLE);
469
470 ReputationAdjustmentResult repF = Global.getSector().adjustPlayerReputation(
471 new RepActionEnvelope(RepActions.MISSION_SUCCESS, completionRep,
472 null, dialog.getTextPanel(), true, true),
473 contact.getFaction().getId());
474 ReputationAdjustmentResult repC = Global.getSector().adjustPlayerReputation(
475 new RepActionEnvelope(RepActions.MISSION_SUCCESS, completionRep,
476 null, dialog.getTextPanel(), true, true),
477 contact);
478 setMissionResult(new MissionResult(reward, repF, repC));
479 setMissionState(MissionState.COMPLETED);
480
481 //sendUpdateIfPlayerHasIntel(missionResult, false);
482 } else if (action.equals("hasEnough")) {
483 return cargo.getCommodityQuantity(commodityId) >= quantity;
484 } else if (action.equals("endEvent")) {
485 endMission();
486// } else if (action.equals("handOver")) {
487// CargoAPI pirateCargo = dialog.getInteractionTarget().getCargo();
488// cargo.removeItems(CargoItemType.RESOURCES, commodityId, quantity);
489// pirateCargo.addItems(CargoItemType.RESOURCES, commodityId, quantity);
490//
491// CampaignFleetAPI pirateFleet = (CampaignFleetAPI) dialog.getInteractionTarget();
492// pirateFleet.getAI().removeFirstAssignment();
493// pirateFleet.getAI().addAssignmentAtStart(FleetAssignment.GO_TO_LOCATION_AND_DESPAWN, market.getPrimaryEntity(), 1000f, null);
494//
495// pirateFleet.getMemoryWithoutUpdate().unset("$mpm_isSpawnedByMPM");
496// pirateFleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_HOSTILE, false, 10);
497 } else if (action.equals("hasBonus")) {
498 return hasBonus();
499 }
500
501 return true;
502 }
503
504 protected boolean hasBonus() {
505 return false;
506 //return (bonusDuration - elapsedDays) > 0;
507 }
508
509 protected void applyTradeValueImpact(float totalReward) {
510 boolean illegal = contact.getFaction().isHostileTo(market.getFaction());
511
512 SubmarketAPI submarket = null;
513 for (SubmarketAPI curr : market.getSubmarketsCopy()) {
514 if (!curr.getPlugin().isParticipatesInEconomy()) continue;
515 if (contact.getFaction() == curr.getFaction()) {
516 submarket = curr;
517 break;
518 }
519 }
520
521 if (submarket == null) {
522 for (SubmarketAPI curr : market.getSubmarketsCopy()) {
523 if (!curr.getPlugin().isParticipatesInEconomy()) continue;
524
525 if (illegal && curr.getPlugin().isBlackMarket()) {
526 submarket = curr;
527 break;
528 }
529 if (!illegal && curr.getPlugin().isOpenMarket()) {
530 submarket = curr;
531 break;
532 }
533 }
534 }
535
536 if (submarket == null) return;
537
538 PlayerTradeDataForSubmarket tradeData = SharedData.getData().getPlayerActivityTracker().getPlayerTradeData(submarket);
539 CargoStackAPI stack = Global.getFactory().createCargoStack(CargoItemType.RESOURCES, commodity.getId(), null);
540 stack.setSize(quantity);
541 tradeData.addToTrackedPlayerSold(stack, totalReward);
542
543 Misc.affectAvailabilityWithinReason(commodity, (int)quantity);
544 }
545
546
547 public void endMission() {
548 if (contact != null) {
549 contact.getMemoryWithoutUpdate().unset("$mpm_isPlayerContact");
550 contact.getMemoryWithoutUpdate().unset("$mpm_eventRef");
551 contact.getMemoryWithoutUpdate().unset("$mpm_commodityName");
552 contact.getMemoryWithoutUpdate().unset("$mpm_quantity");
553 Misc.setFlagWithReason(contact.getMemoryWithoutUpdate(),
554 MemFlags.MEMORY_KEY_REQUIRES_DISCRETION, "mpm_" + commodity.getId(),
555 false, 0f);
556 Misc.setFlagWithReason(contact.getMemoryWithoutUpdate(),
557 MemFlags.MEMORY_KEY_MISSION_IMPORTANT,
558 "mpm", false, 0f);
559
561 contact.decrWantsToContactReasons();
562 }
563
564 Global.getSector().getImportantPeople().returnPerson(contact, PERSON_CHECKOUT_REASON);
565 if (!Global.getSector().getImportantPeople().isCheckedOutForAnything(contact)) {
566 market.getCommDirectory().removePerson(contact);
567 //mission.getMarket().removePerson(mission.getContact());
568 }
569 }
570
572 }
573
574 public boolean runWhilePaused() {
575 return false;
576 }
577
578 protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
579
580 Color h = Misc.getHighlightColor();
581 Color g = Misc.getGrayColor();
582 float pad = 3f;
583 float opad = 10f;
584
585 float initPad = pad;
586 if (mode == ListInfoMode.IN_DESC) initPad = opad;
587
588 Color tc = getBulletColorForMode(mode);
589
590 bullet(info);
591 boolean isUpdate = getListInfoParam() != null;
592
593 if (isUpdate) {
594 // 3 possible updates: de-posted/expired, failed, completed
595 if (isFailed() || isCancelled()) {
596 return;
597 } else if (isCompleted()) {
598 if (missionResult.payment > 0) {
599 info.addPara("%s received", initPad, tc, h, Misc.getDGSCredits(missionResult.payment));
600 }
601 CoreReputationPlugin.addAdjustmentMessage(missionResult.rep1.delta, contact.getFaction(), null,
602 null, null, info, tc, isUpdate, 0f);
604 null, null, info, tc, isUpdate, 0f);
605 }
606 } else {
607 // either in small description, or in tooltip/intel list
608 if (missionResult != null) {
609 if (missionResult.payment > 0) {
610 info.addPara("%s received", initPad, tc, h, Misc.getDGSCredits(missionResult.payment));
611 initPad = 0f;
612 }
613
614 if (missionResult.rep1 != null) {
615 CoreReputationPlugin.addAdjustmentMessage(missionResult.rep1.delta, contact.getFaction(), null,
616 null, null, info, tc, isUpdate, initPad);
617 initPad = 0f;
618 }
619 if (missionResult.rep2!= null) {
621 null, null, info, tc, isUpdate, initPad);
622 initPad = 0f;
623 }
624 } else {
625 if (mode != ListInfoMode.IN_DESC) {
626 FactionAPI faction = contact.getFaction();
627 info.addPara("Faction: " + faction.getDisplayName(), initPad, tc,
628 faction.getBaseUIColor(),
629 faction.getDisplayName());
630 initPad = 0f;
631 }
632
633 LabelAPI label = info.addPara("%s units required at " + market.getName(),
634 initPad, tc, h, "" + (int) quantity);
635 label.setHighlight("" + (int)quantity, market.getName());
636 label.setHighlightColors(h, market.getFaction().getBaseUIColor());
637 info.addPara("%s reward", 0f, tc, h, Misc.getDGSCredits(baseReward));
638 addDays(info, "to complete", duration - elapsedDays, tc, 0f);
639 }
640 }
641
642 unindent(info);
643 }
644
645 @Override
646 public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
647 Color h = Misc.getHighlightColor();
648 Color g = Misc.getGrayColor();
649 Color c = getTitleColor(mode);
650 float pad = 3f;
651 float opad = 10f;
652
653 info.addPara(getName(), c, 0f);
654
655 addBulletPoints(info, mode);
656 }
657
658 public String getSortString() {
659 return "Procurement";
660 }
661
662 public String getName() {
663 if (isAccepted() || isPosted()) {
664 return "Procurement - " + commodity.getCommodity().getName();
665 }
666
667 return "Procurement Contract" + getPostfixForState();
668 }
669
670 @Override
671 public FactionAPI getFactionForUIColors() {
672 return contact.getFaction();
673 }
674
675 public String getSmallDescriptionTitle() {
676 return getName();
677 }
678
679
680 @Override
681 public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
682 Color h = Misc.getHighlightColor();
683 Color g = Misc.getGrayColor();
684 Color tc = Misc.getTextColor();
685 float pad = 3f;
686 float opad = 10f;
687
688 FactionAPI faction = contact.getFaction();
689 boolean illegal = contact.getFaction().isHostileTo(market.getFaction());
690
691 //info.addImage(commodity.getCommodity().getIconName(), width, 80, opad);
692
693 info.addImages(width, 80, opad, opad * 2f,
694 commodity.getCommodity().getIconName(),
695 contact.getPortraitSprite());
696 //faction.getCrest());
697
698 String prefix = faction.getPersonNamePrefix();
699 if (Factions.PIRATES.equals(faction.getId())) {
700 prefix += "-affiliated";
701 }
702
703 String desc = contact.getPost();
704 if (desc == null) desc = contact.getRank();
705 if (desc == null) desc = "supplier";
706 desc = desc.toLowerCase();
707
708
709 info.addPara(Misc.ucFirst(faction.getPersonNamePrefixAOrAn()) + " " + prefix + " " + desc + " at " +
710 market.getName() + " " +
711 "has posted a procurement contract for a quantity of " +
712 commodity.getCommodity().getLowerCaseName() + ".",
713 opad, tc, faction.getBaseUIColor(), prefix);
714
715
716
717 if (isPosted() || isAccepted()) {
718
719 addBulletPoints(info, ListInfoMode.IN_DESC);
720
721 info.addPara("Contact " + contact.getNameString() +
722 " at " + market.getName() + " to complete the delivery.", opad);
723
724 if (illegal) {
725 info.addPara(contact.getNameString() +
726 " is affiliated with the local underworld and will require clandestine delivery, " +
727 "which may attract the interest of local authorities.", opad);
728 } else {
729 if (market.getFaction().isHostileTo(Factions.PLAYER)) {
730 info.addPara(contact.getNameString() + " is " +
731 "operating with the knowledge of the local authorities. " +
732 "However, " + faction.getDisplayNameWithArticle() + " is hostile towards you, and you'll need " +
733 "to sneak into port without attracting notice in order to complete the delivery.", opad);
734 } else {
735 info.addPara(contact.getNameString() + " is " +
736 "operating with the knowledge of the local authorities and the delivery may be made openly.", opad);
737 }
738 }
739
741
742 addAcceptOrAbandonButton(info, width);
743
744 ButtonAPI button = info.addButton("View commodity info", BUTTON_COMMODITY_INFO,
745 getFactionForUIColors().getBaseUIColor(), getFactionForUIColors().getDarkUIColor(),
746 (int)(width), 20f, opad * 3f);
747 if (!Global.getSector().getIntelManager().isPlayerInRangeOfCommRelay()) {
748 button.setEnabled(false);
749 info.addPara("Seeing remote price data requires being within range of a functional comm relay.", g, opad);
750 }
751
752
753 } else {
754 if (isFailed() && !market.isInEconomy()) {
755 info.addPara("You have failed this contract because " + market.getName() +
756 " no longer exists as a functional polity.", opad);
757 } else {
759 }
760
761 addBulletPoints(info, ListInfoMode.IN_DESC);
762 }
763
764 }
765
766 public String getIcon() {
767 return commodity.getCommodity().getIconName();
768 }
769
770 public Set<String> getIntelTags(SectorMapAPI map) {
771 Set<String> tags = super.getIntelTags(map);
772 tags.add(Tags.INTEL_TRADE);
773 tags.add(contact.getFaction().getId());
774 return tags;
775 }
776
777
778 @Override
779 public SectorEntityToken getMapLocation(SectorMapAPI map) {
780 return market.getPrimaryEntity();
781 }
782
783
784
785 @Override
786 protected String getMissionTypeNoun() {
787 return "contract";
788 }
789
790
791 @Override
792 protected MissionResult createAbandonedResult(boolean withPenalty) {
793 if (withPenalty) {
794 float repAmount = 0.01f * baseReward / 100000f;
795 if (repAmount < 0.01f) repAmount = 0.01f;
796 if (repAmount > 0.05f) repAmount = 0.05f;
797
798 MissionCompletionRep completionRep = new MissionCompletionRep(repAmount, RepLevel.WELCOMING, -repAmount, RepLevel.INHOSPITABLE);
799
800 ReputationAdjustmentResult repF = Global.getSector().adjustPlayerReputation(
801 new RepActionEnvelope(RepActions.MISSION_FAILURE, completionRep,
802 null, null, true, false),
803 contact.getFaction().getId());
804 ReputationAdjustmentResult repC = Global.getSector().adjustPlayerReputation(
805 new RepActionEnvelope(RepActions.MISSION_FAILURE, completionRep,
806 null, null, true, false),
807 contact);
808
809 return new MissionResult(0, repF, repC);
810 }
811
812 return new MissionResult();
813 }
814
815 @Override
816 protected MissionResult createTimeRanOutFailedResult() {
817 return createAbandonedResult(true);
818 }
819
820
821 @Override
822 public void buttonPressConfirmed(Object buttonId, IntelUIAPI ui) {
823 if (buttonId == BUTTON_COMMODITY_INFO) {
824 return;
825 }
826 super.buttonPressConfirmed(buttonId, ui);
827 }
828
829
830 @Override
831 public void createConfirmationPrompt(Object buttonId, TooltipMakerAPI prompt) {
832 if (buttonId != BUTTON_COMMODITY_INFO) {
833 super.createConfirmationPrompt(buttonId, prompt);
834 return;
835 }
836
837 prompt.setParaFontDefault();
838
839 prompt.addPara("This procurement contract offers a price of %s per unit of " + commodity.getCommodity().getName() + ".",
840 0f, Misc.getHighlightColor(), Misc.getDGSCredits(pricePerUnit));
841
842 Global.getSettings().addCommodityInfoToTooltip(prompt, 10f, commodity.getCommodity(), 10, true, false, true);
843 }
844
845 @Override
846 public boolean doesButtonHaveConfirmDialog(Object buttonId) {
847 if (buttonId == BUTTON_COMMODITY_INFO) {
848 return true;
849 }
850 return super.doesButtonHaveConfirmDialog(buttonId);
851 }
852
853 public float getConfirmationPromptWidth(Object buttonId) {
854 if (buttonId == BUTTON_COMMODITY_INFO) {
855 return 664f + 43f + 10f;
856 }
857 return super.getConfirmationPromptWidth(buttonId);
858 }
859
860 public String getConfirmText(Object buttonId) {
861 if (buttonId == BUTTON_COMMODITY_INFO) {
862 return "Dismiss";
863 }
864 return super.getConfirmText(buttonId);
865 }
866
867 public String getCancelText(Object buttonId) {
868 if (buttonId == BUTTON_COMMODITY_INFO) {
869 return null;
870 }
871 return super.getCancelText(buttonId);
872 }
873
874
875}
876
877
static SettingsAPI getSettings()
Definition Global.java:51
static FactoryAPI getFactory()
Definition Global.java:35
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 setPostingLocation(SectorEntityToken postingLocation)
void addDays(TooltipMakerAPI info, String after, float days)
void addAcceptOrAbandonButton(TooltipMakerAPI info, float width)
boolean doNearbyMarketsHave(MarketAPI from, String commodityId, float minQty)
void createSmallDescription(TooltipMakerAPI info, float width, float height)
float getQuantityAdjustedForMarket(String commodityId, float quantity, float illegalMult, float min, MarketAPI market)
void createConfirmationPrompt(Object buttonId, TooltipMakerAPI prompt)
static PersonDataAPI getLegitTrader(MarketAPI market, String checkoutReason, String factionId)
boolean callEvent(String ruleId, final InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
MarketAPI pickMarket(String commodityId, float quantity, float illegalMult, float min)
PersonAPI pickContact(MarketAPI market, CommodityOnMarketAPI com)
static PersonDataAPI getCriminal(MarketAPI market, String checkoutReason, String factionId)
CargoStackAPI createCargoStack(CargoItemType type, Object data, CargoAPI cargo)
void addCommodityInfoToTooltip(TooltipMakerAPI tooltip, float initPad, CommoditySpecAPI spec, int max, boolean withText, boolean withSell, boolean withBuy)
CommoditySpecAPI getCommoditySpec(String commodityId)