001package com.fs.starfarer.api.impl.campaign.missions;
002
003import java.awt.Color;
004
005import com.fs.starfarer.api.campaign.FactionAPI;
006import com.fs.starfarer.api.campaign.PersonImportance;
007import com.fs.starfarer.api.campaign.econ.MarketAPI;
008import com.fs.starfarer.api.characters.PersonAPI;
009import com.fs.starfarer.api.impl.campaign.ids.Factions;
010import com.fs.starfarer.api.impl.campaign.ids.Ranks;
011import com.fs.starfarer.api.impl.campaign.ids.Tags;
012import com.fs.starfarer.api.impl.campaign.intel.bases.LuddicPathBaseIntel;
013import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel;
014import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
015import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.RaidDangerLevel;
016import com.fs.starfarer.api.ui.LabelAPI;
017import com.fs.starfarer.api.ui.TooltipMakerAPI;
018import com.fs.starfarer.api.util.Misc;
019
020public class ExtractionMission extends HubMissionWithBarEvent {
021
022        public static float PROB_BASE_INSTEAD_OF_MARKET_MIN = 0.25f;
023        public static float PROB_BASE_INSTEAD_OF_MARKET_MAX = 0.75f;
024        public static float PROB_PIRATE_BASE_WHEN_BASE = 0.5f;
025        
026        public static float PROB_ADDITIONAL_PATROLS = 0.5f;
027        
028        public static float MISSION_DAYS = 120f;
029        
030        public static enum Variation {
031                COLONY,
032                PIRATE_BASE,
033                LUDDIC_PATH_BASE,
034        }
035        
036        public static enum Stage {
037                EXTRACT,
038                RETURN,
039                COMPLETED,
040                FAILED,
041                FAILED_DECIV,
042        }
043        
044        protected Variation variation;
045        protected MarketAPI market;
046        protected RaidDangerLevel danger;
047        protected int storyCost = 0;
048        protected String seedyBarOwner;
049        
050        @Override
051        protected boolean create(MarketAPI createdAt, boolean barEvent) {
052                //genRandom = Misc.random;
053
054                if (Factions.PIRATES.equals(createdAt.getFaction().getId())) return false;
055                
056                if (barEvent) {
057                        setGiverRank(Ranks.CITIZEN);
058                        setGiverPost(Ranks.POST_AGENT);
059                        setGiverImportance(pickImportance());
060                        setGiverTags(Tags.CONTACT_MILITARY);
061                        findOrCreateGiver(createdAt, true, false);
062                }
063                
064                PersonAPI person = getPerson();
065                if (person == null) return false;
066                
067                if (!setPersonMissionRef(person, "$extr_ref")) {
068                        return false;
069                }
070                
071                if (barEvent) {
072                        setGiverIsPotentialContactOnSuccess();
073                }
074                
075                seedyBarOwner = pickOne("Eduardo",
076                                                                "Roy", 
077                                                                "Hyde",
078                                                                "Shang",
079                                                                "Rick",
080                                                                "Bogdan",
081                                                                "William",
082                                                                "Marlowe",
083                                                                "Benny"
084                                );
085                
086                PersonImportance importance = person.getImportance();
087                int minMarketSize = 3;
088                int maxMarketSize = 9;
089                switch (importance) {
090                case VERY_LOW:
091                        minMarketSize = 3;
092                        maxMarketSize = 4;
093                        break;
094                case LOW:
095                        minMarketSize = 4;
096                        maxMarketSize = 4;
097                        break;
098                case MEDIUM:
099                        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 + 
114                                        (PROB_BASE_INSTEAD_OF_MARKET_MAX - 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                if (getPerson() == null || getPerson().getMarket() == null) return;
244                
245                float opad = 10f;
246                Color h = Misc.getHighlightColor();
247                if (currentStage == Stage.EXTRACT) {
248                        info.addPara("Extract agent located " +
249                                         market.getOnOrAt() + " " + market.getName() + 
250                                         " in the " + market.getStarSystem().getNameWithLowercaseTypeShort() + ".", opad);
251                        if (variation == Variation.PIRATE_BASE || variation == Variation.LUDDIC_PATH_BASE) {
252                                FactionAPI f = market.getFaction();
253                                info.addPara("The target location is " + f.getPersonNamePrefixAOrAn() + " %s base.",
254                                                         opad, f.getBaseUIColor(), f.getPersonNamePrefix());
255                                
256//                              info.addPara("The operation will require a sizeable marine contingent and will face active " +
257//                                              "resistance. A close assessment of the station's internal defenses is " +
258//                                              "required to determine the forces necessary.", opad);
259                        } else {
260                                FactionAPI f = market.getFaction();
261                                LabelAPI label = info.addPara("The target location is a size %s " +
262                                                                "colony controlled by " + f.getDisplayNameWithArticle() + ".",
263                                                         opad, f.getBaseUIColor(),
264                                                         "" + market.getSize(), f.getDisplayNameWithArticleWithoutArticle());
265                                label.setHighlight("" + market.getSize(), f.getDisplayNameWithArticleWithoutArticle());
266                                label.setHighlightColors(h, f.getBaseUIColor());
267                                
268//                              info.addPara("The operation will require a sizeable marine contingent and will face active " +
269//                                              "resistance. A close assessment of the colony's ground defenses is " +
270//                                              "required to determine the forces necessary.", opad);
271                        }
272                        addCustomRaidInfo(market, danger, info, opad);
273                        
274                } else if (currentStage == Stage.RETURN) {
275                        info.addPara(getReturnText(getPerson().getMarket().getName()) + ".", opad);
276                }
277        }
278
279        @Override
280        public boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad) {
281                if (getPerson() == null || getPerson().getMarket() == null) return false;
282                
283                Color h = Misc.getHighlightColor();
284                if (currentStage == Stage.EXTRACT) {
285                                info.addPara("Extract agent from " +
286                                                         market.getName() + 
287                                                         " in the " + market.getStarSystem().getNameWithLowercaseTypeShort() + ".", pad, tc,
288                                                         market.getFaction().getBaseUIColor(), market.getName());
289                                return true;
290                } else if (currentStage == Stage.RETURN) {
291                        info.addPara(getReturnTextShort(getPerson().getMarket().getName()), tc, pad);
292                        return true;
293                }
294                return false;
295        }       
296        
297        @Override
298        public String getBaseName() {
299                return "Combat Extraction";
300        }
301}
302
303
304
305