1package com.fs.starfarer.api.impl.campaign.missions;
4import java.util.ArrayList;
9import org.lwjgl.util.vector.Vector2f;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.InteractionDialogAPI;
13import com.fs.starfarer.api.campaign.PersonImportance;
14import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
15import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
16import com.fs.starfarer.api.campaign.econ.MarketAPI;
17import com.fs.starfarer.api.campaign.econ.MonthlyReport;
18import com.fs.starfarer.api.campaign.econ.MonthlyReport.FDNode;
19import com.fs.starfarer.api.campaign.listeners.EconomyTickListener;
20import com.fs.starfarer.api.campaign.rules.MemoryAPI;
21import com.fs.starfarer.api.characters.PersonAPI;
22import com.fs.starfarer.api.impl.campaign.ids.Commodities;
23import com.fs.starfarer.api.impl.campaign.ids.Factions;
24import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
25import com.fs.starfarer.api.impl.campaign.ids.Ranks;
26import com.fs.starfarer.api.impl.campaign.ids.Tags;
27import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
28import com.fs.starfarer.api.impl.campaign.shared.SharedData;
29import com.fs.starfarer.api.ui.SectorMapAPI;
30import com.fs.starfarer.api.ui.TooltipMakerAPI;
31import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
32import com.fs.starfarer.api.util.Misc;
33import com.fs.starfarer.api.util.WeightedRandomPicker;
50 public static enum Stage {
57 public static enum Variation {
62 public static class CheckPlayerProduction
implements ConditionChecker {
63 protected String commodityId;
64 protected int quantity;
65 public CheckPlayerProduction(String commodityId,
int quantity) {
66 this.commodityId = commodityId;
67 this.quantity = quantity;
69 public boolean conditionsMet() {
88 protected boolean create(MarketAPI createdAt,
boolean barEvent) {
91 setGiverRank(Ranks.CITIZEN);
92 String post = pickOne(Ranks.POST_TRADER, Ranks.POST_COMMODITIES_AGENT, Ranks.POST_PORTMASTER,
93 Ranks.POST_MERCHANT, Ranks.POST_INVESTOR, Ranks.POST_EXECUTIVE,
94 Ranks.POST_SENIOR_EXECUTIVE);
96 if (post.equals(Ranks.POST_SENIOR_EXECUTIVE)) {
97 setGiverImportance(pickHighImportance());
99 setGiverImportance(pickImportance());
102 setGiverTags(Tags.CONTACT_UNDERWORLD);
103 setGiverFaction(Factions.PIRATES);
105 setGiverTags(Tags.CONTACT_TRADE);
107 findOrCreateGiver(createdAt,
false,
false);
110 PersonAPI person = getPerson();
111 if (person ==
null)
return false;
113 if (!setPersonMissionRef(person,
"$cpm_ref")) {
118 setGiverIsPotentialContactOnSuccess();
121 PersonImportance importance = person.getImportance();
124 switch (importance) {
147 needed = minNeeded + genRandom.nextInt(maxNeeded - minNeeded + 1);
149 MarketAPI market = getPerson().getMarket();
150 if (market ==
null)
return false;
151 if (market.isPlayerOwned())
return false;
153 WeightedRandomPicker<String> commoditiesPlayerIsNotProducing =
new WeightedRandomPicker<String>(genRandom);
154 WeightedRandomPicker<String> commoditiesPlayerIsProducing =
new WeightedRandomPicker<String>(genRandom);
156 List<String> all =
new ArrayList<String>();
158 if (
spec.isPersonnel())
continue;
159 if (
spec.isMeta())
continue;
160 if (
spec.isNonEcon())
continue;
161 if (!
spec.isPrimary())
continue;
163 if (market.getCommodityData(
spec.getId()).getMaxDemand() < minNeeded / 2)
continue;
165 boolean illegal = market.isIllegal(
spec.getId());
166 if (illegal && !person.hasTag(Tags.CONTACT_UNDERWORLD))
continue;
167 if (!illegal && !person.hasTag(Tags.CONTACT_TRADE))
continue;
169 all.add(
spec.getId());
172 for (String cid : all) {
173 commoditiesPlayerIsNotProducing.add(cid);
174 for (MarketAPI curr : Misc.getPlayerMarkets(
true)) {
175 CommodityOnMarketAPI com = curr.getCommodityData(cid);
176 if (com.getMaxSupply() > 0) {
177 commoditiesPlayerIsProducing.add(cid, Math.max(1, 10 - com.getMaxSupply()));
178 commoditiesPlayerIsNotProducing.remove(cid);
183 commodityId = commoditiesPlayerIsNotProducing.pick();
198 Variation.NOT_PRODUCING : Variation.PRODUCING_ALREADY;
202 float basePayment = 1000 +
getSpec().getBasePrice() * 10;
203 if (
variation == Variation.NOT_PRODUCING) {
214 setStartingStage(Stage.WAITING);
215 setSuccessStage(Stage.COMPLETED);
216 setFailureStage(Stage.FAILED);
218 connectWithCustomCondition(Stage.WAITING, Stage.PAYING,
new CheckPlayerProduction(
commodityId,
needed));
219 setTimeLimit(Stage.FAILED,
MISSION_DAYS,
null, Stage.PAYING);
227 public void setCurrentStage(Object next, InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
228 super.setCurrentStage(next, dialog, memoryMap);
230 if (next == Stage.PAYING) {
231 addPotentialContacts(dialog);
238 set(
"$cpm_barEvent", isBarEvent());
239 set(
"$cpm_manOrWoman", getPerson().getManOrWoman());
241 set(
"$cpm_underworld", getPerson().hasTag(Tags.CONTACT_UNDERWORLD));
242 set(
"$cpm_totalPayment", Misc.getWithDGS(
totalPayment));
245 set(
"$cpm_commodityName",
getSpec().getLowerCaseName());
246 set(
"$cpm_needed",
needed);
247 set(
"$cpm_playerHasColony", !Misc.getPlayerMarkets(
false).isEmpty());
253 Color h = Misc.getHighlightColor();
254 if (currentStage == Stage.WAITING) {
255 info.addPara(
"Produce at least %s units of " +
getSpec().getLowerCaseName() +
" at " +
256 "a colony under your control.", opad, h,
"" +
needed);
257 info.addPara(
"Once these terms are met, you will receive %s per month for the next " +
258 "%s cycles, for a total of %s, as long as production is maintained.", opad, h,
263 info.addPara(
"You will need to survey a suitable planet and establish a colony to complete " +
264 "this mission.", opad);
266 }
else if (currentStage == Stage.PAYING) {
267 info.addPara(
"You've met the initial terms of the contract to produce %s units of " +
268 getSpec().getLowerCaseName() +
" at " +
269 "a colony under your control.", opad, h,
"" +
needed);
270 info.addPara(
"As long these terms are met, you will receive %s per month over %s cycles for " +
271 "a total payout of %s, assuming there is no interruption in production.", opad, h,
277 info.addPara(
"You are currently meeting the terms of the contract.",
278 Misc.getPositiveHighlightColor(), opad);
280 info.addPara(
"You are not currently meeting the terms of the contract.",
281 Misc.getNegativeHighlightColor(), opad);
283 }
else if (currentStage == Stage.COMPLETED) {
284 info.addPara(
"The contract is completed.", opad);
290 Color h = Misc.getHighlightColor();
291 if (currentStage == Stage.WAITING) {
292 info.addPara(
"Produce at least %s units of " +
getSpec().getLowerCaseName() +
" at " +
293 "a colony", pad, tc, h,
"" +
needed);
295 }
else if (currentStage == Stage.PAYING) {
296 info.addPara(
"Receiving %s per month", pad, tc, h, Misc.getDGSCredits(
monthlyPayment));
299 info.addPara(
"Terms of contract met", tc, 0f);
301 info.addPara(
"Terms of contract not met",
302 Misc.getNegativeHighlightColor(), 0f);
311 return getSpec().getName() +
" Production";
316 return !Misc.getPlayerMarkets(
true).isEmpty();
319 for (MarketAPI market : Misc.getPlayerMarkets(
true)) {
320 CommodityOnMarketAPI com = market.getCommodityData(
commodityId);
321 if (com.getMaxSupply() >= quantity)
return true;
326 protected transient CommoditySpecAPI
spec;
337 super.notifyEnding();
342 public void acceptImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
343 super.acceptImpl(dialog, memoryMap);
357 e.
triggerCreateFleet(FleetSize.VERY_LARGE, FleetQuality.DEFAULT, Factions.PIRATES, FleetTypes.PATROL_LARGE,
new Vector2f());
359 e.triggerSetStandardAggroPirateFlags();
361 e.triggerSetFleetMemoryValue(
"$cpm_commodityName",
getSpec().getLowerCaseName());
362 e.triggerSetFleetGenericHailPermanent(
"CPMPirateHail");
368 return "$" + getMissionId() +
"_" +
commodityId +
"_" +
uid +
"_completed";
373 if (currentStage != Stage.PAYING)
return;
377 MonthlyReport report = SharedData.getData().getCurrentReport();
378 FDNode colonyNode = report.getNode(MonthlyReport.OUTPOSTS);
379 FDNode paymentNode = report.getNode(colonyNode, getMissionId() +
"_" +
commodityId +
"_" +
uid);
383 paymentNode.icon =
getSpec().getIconName();
384 paymentNode.tooltipCreator =
this;
396 public void createTooltip(TooltipMakerAPI tooltip,
boolean expanded, Object tooltipParam) {
397 tooltip.addSpacer(-10f);
415 Set<String> tags = super.getIntelTags(map);
416 if (currentStage == Stage.PAYING) {
417 tags.add(Tags.INTEL_AGREEMENTS);
418 tags.remove(Tags.INTEL_ACCEPTED);
static SettingsAPI getSettings()
static SectorAPI getSector()
void updateInteractionDataImpl()
static float PROB_COMPLICATIONS
void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam)
static float MISSION_DAYS
boolean create(MarketAPI createdAt, boolean barEvent)
Set< String > getIntelTags(SectorMapAPI map)
static float REWARD_MULT_WHEN_PRODUCING_ALREADY
void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height)
void reportEconomyTick(int iterIndex)
void reportEconomyMonthEnd()
float getTooltipWidth(Object tooltipParam)
static int CONTRACT_CYCLES
static float PROB_UNDERWORLD_BAR
static int MISSION_CYCLES
boolean isTooltipExpandable(Object tooltipParam)
transient CommoditySpecAPI spec
static float REWARD_MULT_WHEN_NOT_PRODUCING_ALREADY
String getCompletionFlag()
static boolean playerHasAColony()
static boolean isPlayerProducing(String commodityId, int quantity)
String getMissionTypeNoun()
void acceptImpl(InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad)
void setCurrentStage(Object next, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
static int CONTRACT_MONTHS
CommoditySpecAPI getSpec()
void triggerCreateFleet(FleetSize size, FleetQuality quality, String factionId, String type, SectorEntityToken roughlyWhere)
void triggerSetStandardAggroInterceptFlags()
void setDelay(float minDays, float maxDays)
void triggerSetAdjustStrengthBasedOnQuality(boolean randomize, float quality)
void setLocationInnerSector(boolean allowInsidePopulatedSystems, String requireLargestMarketNotHostileToFaction)
CommoditySpecAPI getCommoditySpec(String commodityId)
float getFloat(String key)
List< CommoditySpecAPI > getAllCommoditySpecs()