Starsector API
Loading...
Searching...
No Matches
ExtractionMission.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.missions;
2
3import java.awt.Color;
4
5import com.fs.starfarer.api.campaign.FactionAPI;
6import com.fs.starfarer.api.campaign.PersonImportance;
7import com.fs.starfarer.api.campaign.econ.MarketAPI;
8import com.fs.starfarer.api.characters.PersonAPI;
9import com.fs.starfarer.api.impl.campaign.ids.Factions;
10import com.fs.starfarer.api.impl.campaign.ids.Ranks;
11import com.fs.starfarer.api.impl.campaign.ids.Tags;
12import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseIntel;
13import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel;
14import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
15import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.RaidDangerLevel;
16import com.fs.starfarer.api.ui.LabelAPI;
17import com.fs.starfarer.api.ui.TooltipMakerAPI;
18import com.fs.starfarer.api.util.Misc;
19
20public class ExtractionMission extends HubMissionWithBarEvent {
21
22 public static float PROB_BASE_INSTEAD_OF_MARKET_MIN = 0.25f;
23 public static float PROB_BASE_INSTEAD_OF_MARKET_MAX = 0.75f;
24 public static float PROB_PIRATE_BASE_WHEN_BASE = 0.5f;
25
26 public static float PROB_ADDITIONAL_PATROLS = 0.5f;
27
28 public static float MISSION_DAYS = 120f;
29
30 public static enum Variation {
31 COLONY,
32 PIRATE_BASE,
33 LUDDIC_PATH_BASE,
34 }
35
36 public static enum Stage {
37 EXTRACT,
38 RETURN,
39 COMPLETED,
40 FAILED,
41 FAILED_DECIV,
42 }
43
44 protected Variation variation;
45 protected MarketAPI market;
46 protected RaidDangerLevel danger;
47 protected int storyCost = 0;
48 protected String seedyBarOwner;
49
50 @Override
51 protected boolean create(MarketAPI createdAt, boolean barEvent) {
52 //genRandom = Misc.random;
53
54 if (Factions.PIRATES.equals(createdAt.getFaction().getId())) return false;
55
56 if (barEvent) {
57 setGiverRank(Ranks.CITIZEN);
58 setGiverPost(Ranks.POST_AGENT);
59 setGiverImportance(pickImportance());
60 setGiverTags(Tags.CONTACT_MILITARY);
61 findOrCreateGiver(createdAt, true, false);
62 }
63
64 PersonAPI person = getPerson();
65 if (person == null) return false;
66
67 if (!setPersonMissionRef(person, "$extr_ref")) {
68 return false;
69 }
70
71 if (barEvent) {
72 setGiverIsPotentialContactOnSuccess();
73 }
74
75 seedyBarOwner = pickOne("Eduardo",
76 "Roy",
77 "Hyde",
78 "Shang",
79 "Rick",
80 "Bogdan",
81 "William",
82 "Marlowe",
83 "Benny"
84 );
85
86 PersonImportance importance = person.getImportance();
87 int minMarketSize = 3;
88 int maxMarketSize = 9;
89 switch (importance) {
90 case VERY_LOW:
91 minMarketSize = 3;
92 maxMarketSize = 4;
93 break;
94 case LOW:
95 minMarketSize = 4;
96 maxMarketSize = 4;
97 break;
98 case MEDIUM:
99 minMarketSize = 5;
100 maxMarketSize = 5;
101 break;
102 case HIGH:
103 minMarketSize = 5;
104 maxMarketSize = 6;
105 break;
106 case VERY_HIGH:
107 minMarketSize = 6;
108 maxMarketSize = 8;
109 break;
110 }
111
112 if (importance.ordinal() >= PersonImportance.HIGH.ordinal()) {
113 float pBase = PROB_BASE_INSTEAD_OF_MARKET_MIN +
115 Math.max(0, getPerson().getRelToPlayer().getRel());
116 if (rollProbability(pBase)) {
117 resetSearch();
118 requireMarketIsNot(createdAt);
119 requireMarketFactionNotPlayer();
120 requireMarketMemoryFlag(PirateBaseIntel.MEM_FLAG, true);
121 requireMarketNotInHyperspace();
122 preferMarketInDirectionOfOtherMissions();
123 MarketAPI pirateBase = pickMarket();
124
125 resetSearch();
126 requireMarketIsNot(createdAt);
127 requireMarketMemoryFlag(LuddicPathBaseIntel.MEM_FLAG, true);
128 requireMarketNotInHyperspace();
129 preferMarketInDirectionOfOtherMissions();
130 MarketAPI pathBase = pickMarket();
131
132 boolean allowPath = !Factions.LUDDIC_PATH.equals(createdAt.getFaction().getId());
133
134 if (rollProbability(PROB_PIRATE_BASE_WHEN_BASE) && pirateBase != null) {
135 market = pirateBase;
136 variation = Variation.PIRATE_BASE;
137 danger = RaidDangerLevel.EXTREME;
138 } else if (allowPath) {
139 market = pathBase;
140 variation = Variation.LUDDIC_PATH_BASE;
141 danger = RaidDangerLevel.EXTREME;
142 }
143 }
144 }
145
146 if (market == null) {
147 resetSearch();
148 requireMarketIsNot(createdAt);
149 requireMarketFactionNotPlayer();
150 requireMarketNotHidden();
151 requireMarketNotInHyperspace();
152 preferMarketSizeAtLeast(minMarketSize);
153 preferMarketSizeAtMost(maxMarketSize);
154 preferMarketFactionHostileTo(createdAt.getFactionId());
155 preferMarketInDirectionOfOtherMissions();
156 market = pickMarket();
157 variation = Variation.COLONY;
158 danger = RaidDangerLevel.MEDIUM;
159 }
160
161 if (market == null) return false;
162 if (!setMarketMissionRef(market, "$extr_ref")) {
163 return false;
164 }
165
166 int marines = getMarinesRequiredForCustomObjective(market, danger);
167 if (!isOkToOfferMissionRequiringMarines(marines)) {
168 return false;
169 }
170
171 makeImportant(market, "$extr_target", Stage.EXTRACT);
172 makeImportant(getPerson(), "$extr_returnHere", Stage.RETURN);
173
174 setStartingStage(Stage.EXTRACT);
175 setSuccessStage(Stage.COMPLETED);
176 addFailureStages(Stage.FAILED);
177
178 connectWithMemoryFlag(Stage.EXTRACT, Stage.RETURN, market, "$extr_needToReturn");
179 setStageOnMemoryFlag(Stage.COMPLETED, person, "$extr_completed");
180
181 addNoPenaltyFailureStages(Stage.FAILED_DECIV);
182 connectWithMarketDecivilized(Stage.EXTRACT, Stage.FAILED_DECIV, market);
183 setStageOnMarketDecivilized(Stage.FAILED_DECIV, createdAt);
184
185 setTimeLimit(Stage.FAILED, MISSION_DAYS, null, Stage.RETURN);
186
187// int sizeModifier = market.getSize() * 10000;
188// if (variation == Variation.PIRATE_BASE || variation == Variation.LUDDIC_PATH_BASE) {
189// sizeModifier = 10 * 10000;;
190// }
191// setCreditReward(10000 + sizeModifier, 30000 + sizeModifier);
192 //int size = market.getSize();
193 int extraBonus = 0;
194 if (variation == Variation.PIRATE_BASE || variation == Variation.LUDDIC_PATH_BASE) {
195 //size = 10;
196 extraBonus = 75000;
197 }
198 //setCreditReward(CreditReward.AVERAGE, size);
199
200 int bonus = getRewardBonusForMarines(getMarinesRequiredForCustomObjective(market, danger));
201 setCreditRewardWithBonus(CreditReward.AVERAGE, bonus + extraBonus);
202
203 storyCost = getRoundNumber(getCreditsReward() / 2);
204
205 if (rollProbability(PROB_ADDITIONAL_PATROLS)) {
206 if (market.getSize() <= 4) {
207 triggerCreateMediumPatrolAroundMarket(market, Stage.EXTRACT, 0f);
208 } else if (market.getSize() <= 6) {
209 triggerCreateLargePatrolAroundMarket(market, Stage.EXTRACT, 0f);
210 } else {
211 triggerCreateMediumPatrolAroundMarket(market, Stage.EXTRACT, 0f);
212 triggerCreateLargePatrolAroundMarket(market, Stage.EXTRACT, 0f);
213 }
214 }
215
216 return true;
217 }
218
219 protected void updateInteractionDataImpl() {
220 set("$extr_variation", variation);
221 set("$extr_barName", seedyBarOwner + "'s");
222 set("$extr_barOwner", seedyBarOwner);
223 set("$extr_barEvent", isBarEvent());
224 set("$extr_manOrWoman", getPerson().getManOrWoman());
225 set("$extr_reward", Misc.getWithDGS(getCreditsReward()));
226 set("$extr_storyCost", Misc.getWithDGS(storyCost));
227
228 set("$extr_systemName", market.getStarSystem().getNameWithLowercaseTypeShort());
229 set("$extr_marketName", market.getName());
230 set("$extr_marketOnOrAt", market.getOnOrAt());
231 set("$extr_marketFactionArticle", market.getFaction().getPersonNamePrefixAOrAn());
232 set("$extr_marketFaction", market.getFaction().getPersonNamePrefix());
233 set("$extr_factionColor", market.getFaction().getBaseUIColor());
234 set("$extr_dist", getDistanceLY(market));
235
236 set("$extr_danger", danger);
237 set("$extr_marines", Misc.getWithDGS(getMarinesRequiredForCustomObjective(market, danger)));
238
239 }
240
241 @Override
242 public void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height) {
243 float opad = 10f;
244 Color h = Misc.getHighlightColor();
245 if (currentStage == Stage.EXTRACT) {
246 info.addPara("Extract agent located " +
247 market.getOnOrAt() + " " + market.getName() +
248 " in the " + market.getStarSystem().getNameWithLowercaseTypeShort() + ".", opad);
249 if (variation == Variation.PIRATE_BASE || variation == Variation.LUDDIC_PATH_BASE) {
250 FactionAPI f = market.getFaction();
251 info.addPara("The target location is " + f.getPersonNamePrefixAOrAn() + " %s base.",
252 opad, f.getBaseUIColor(), f.getPersonNamePrefix());
253
254// info.addPara("The operation will require a sizeable marine contingent and will face active " +
255// "resistance. A close assessment of the station's internal defenses is " +
256// "required to determine the forces necessary.", opad);
257 } else {
258 FactionAPI f = market.getFaction();
259 LabelAPI label = info.addPara("The target location is a size %s " +
260 "colony controlled by " + f.getDisplayNameWithArticle() + ".",
261 opad, f.getBaseUIColor(),
262 "" + market.getSize(), f.getDisplayNameWithArticleWithoutArticle());
263 label.setHighlight("" + market.getSize(), f.getDisplayNameWithArticleWithoutArticle());
264 label.setHighlightColors(h, f.getBaseUIColor());
265
266// info.addPara("The operation will require a sizeable marine contingent and will face active " +
267// "resistance. A close assessment of the colony's ground defenses is " +
268// "required to determine the forces necessary.", opad);
269 }
270 addCustomRaidInfo(market, danger, info, opad);
271
272 } else if (currentStage == Stage.RETURN) {
273 info.addPara(getReturnText(getPerson().getMarket().getName()) + ".", opad);
274 }
275 }
276
277 @Override
278 public boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad) {
279 Color h = Misc.getHighlightColor();
280 if (currentStage == Stage.EXTRACT) {
281 info.addPara("Extract agent from " +
282 market.getName() +
283 " in the " + market.getStarSystem().getNameWithLowercaseTypeShort() + ".", pad, tc,
284 market.getFaction().getBaseUIColor(), market.getName());
285 return true;
286 } else if (currentStage == Stage.RETURN) {
287 info.addPara(getReturnTextShort(getPerson().getMarket().getName()), tc, pad);
288 return true;
289 }
290 return false;
291 }
292
293 @Override
294 public String getBaseName() {
295 return "Combat Extraction";
296 }
297}
298
299
300
301
boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad)
void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height)
boolean create(MarketAPI createdAt, boolean barEvent)