001package com.fs.starfarer.api.impl.campaign.missions;
002
003import java.awt.Color;
004import java.util.List;
005import java.util.Map;
006
007import org.lwjgl.util.vector.Vector2f;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.campaign.CargoAPI;
011import com.fs.starfarer.api.campaign.FactionAPI;
012import com.fs.starfarer.api.campaign.InteractionDialogAPI;
013import com.fs.starfarer.api.campaign.econ.Industry;
014import com.fs.starfarer.api.campaign.econ.MarketAPI;
015import com.fs.starfarer.api.campaign.listeners.ColonyPlayerHostileActListener;
016import com.fs.starfarer.api.campaign.listeners.MarineLossesStatModifier;
017import com.fs.starfarer.api.campaign.rules.MemoryAPI;
018import com.fs.starfarer.api.characters.PersonAPI;
019import com.fs.starfarer.api.combat.MutableStat;
020import com.fs.starfarer.api.impl.campaign.graid.GroundRaidObjectivePlugin;
021import com.fs.starfarer.api.impl.campaign.ids.Factions;
022import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
023import com.fs.starfarer.api.impl.campaign.ids.Ranks;
024import com.fs.starfarer.api.impl.campaign.ids.Tags;
025import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithBarEvent;
026import com.fs.starfarer.api.impl.campaign.missions.hub.ReqMode;
027import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.TempData;
028import com.fs.starfarer.api.ui.LabelAPI;
029import com.fs.starfarer.api.ui.TooltipMakerAPI;
030import com.fs.starfarer.api.util.Misc;
031
032public class SecurityCodes extends HubMissionWithBarEvent implements ColonyPlayerHostileActListener,
033                                                                                                                                 MarineLossesStatModifier {
034
035        public static enum Stage {
036                ACTIVE,
037                COMPLETED,
038        }
039        
040        public static float MARINE_LOSSES_MULT = 0.05f;
041        
042        public static float PROB_COMPLICATIONS = 0.5f;
043        public static float PROB_PATROL_ENCOUNTER_AFTER = 0.5f;
044        
045        public static float MIN_DAYS = 30f;
046        public static float MAX_DAYS = 90f;
047        
048        public static float BASE_PRICE = 30000;
049        
050        protected int price;
051        protected FactionAPI faction;
052        protected int days;
053        
054        
055        @Override
056        protected boolean create(MarketAPI createdAt, boolean barEvent) {
057                if (barEvent) {
058                        setGiverRank(Ranks.CITIZEN);
059                        setGiverPost(pickOne(Ranks.POST_AGENT, Ranks.POST_SMUGGLER, Ranks.POST_GANGSTER, 
060                                                                 Ranks.POST_FENCE, Ranks.POST_CRIMINAL));
061                        setGiverImportance(pickImportance());
062                        setGiverFaction(Factions.PIRATES);
063                        setGiverTags(Tags.CONTACT_UNDERWORLD);
064                        findOrCreateGiver(createdAt, false, false);
065                }
066                
067                PersonAPI person = getPerson();
068                if (person == null) return false;
069                
070                if (!setPersonMissionRef(person, "$seco_ref")) {
071                        return false;
072                }
073                
074                requireMarketFactionNotPlayer();
075                requireMarketFactionCustom(ReqMode.NOT_ANY, Factions.CUSTOM_DECENTRALIZED);
076                requireMarketNotHidden();
077                requireMarketNotInHyperspace();
078                
079                MarketAPI market = pickMarket();
080                if (market == null) return false;
081                
082                faction = market.getFaction();
083                if (faction == null) return false;
084                if (!setFactionMissionRef(faction, "$seco_ref")) {
085                        return false;
086                }
087                
088                price = getRoundNumber((BASE_PRICE * (getQuality() + 0.9f + 0.2f * genRandom.nextFloat())) / getRewardMult());
089                
090                setStartingStage(Stage.ACTIVE);
091                setSuccessStage(Stage.COMPLETED);
092                
093                setNoAbandon();
094                setRepPersonChangesVeryLow();
095                setRepFactionChangesTiny();
096                
097                days = (int)Math.round(MIN_DAYS + (MAX_DAYS - MIN_DAYS) * getQuality());
098                setStageOnMemoryFlag(Stage.COMPLETED, faction, "$seco_completed");
099                setTimeLimit(Stage.COMPLETED, days, null);
100                
101                if (rollProbability(PROB_COMPLICATIONS)) {
102                        triggerComplicationBegin(Stage.ACTIVE, ComplicationSpawn.EXITING_SYSTEM,
103                                        createdAt.getStarSystem(), Factions.PIRATES,
104                                        "the security codes", "they", "the " + faction.getPersonNamePrefix() + " security codes",
105                                        0,
106                                        true, ComplicationRepImpact.NONE, null);
107                        triggerComplicationEnd(true);
108                }
109                
110                //addTempIntel();
111                return true;
112        }
113        
114        protected void updateInteractionDataImpl() {
115                set("$seco_barEvent", isBarEvent());
116                set("$seco_price", Misc.getWithDGS(price));
117                set("$seco_manOrWoman", getPerson().getManOrWoman());
118                set("$seco_hisOrHer", getPerson().getHisOrHer());
119                set("$seco_heOrShe", getPerson().getHeOrShe());
120                set("$seco_days", days);
121                set("$seco_faction", faction.getPersonNamePrefix());
122                set("$seco_factionColor", faction.getBaseUIColor());
123        }
124        
125        @Override
126        public void addDescriptionForCurrentStage(TooltipMakerAPI info, float width, float height) {
127                float opad = 10f;
128                Color h = Misc.getHighlightColor();
129                if (currentStage == Stage.ACTIVE) {
130                        FactionAPI f = faction;
131                        String percent = "" + (int) Math.round((1f - MARINE_LOSSES_MULT) * 100f) + "%";
132                        LabelAPI label = info.addPara("You've acquired ground-forces security codes for %s." + 
133                                        " Having these allows for much better raid planning " +
134                                                        "and will reduce marine casualties by %s.",
135                                        opad, f.getBaseUIColor(),
136                                        f.getDisplayNameWithArticle(), percent);
137                        label.setHighlight(f.getDisplayNameWithArticleWithoutArticle(), percent);
138                        label.setHighlightColors(f.getBaseUIColor(), h);
139                        
140                        info.addPara("The codes are only good for one operation, and, if not used, " +
141                                                 "will also expire after a time.", opad);
142                }
143        }
144
145        @Override
146        public boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad) {
147                Color h = Misc.getHighlightColor();
148                if (currentStage == Stage.ACTIVE) {
149//                      info.addPara("Have security codes for " + faction.getDisplayName(), tc, pad);
150//                      return true;
151                }
152                return false;
153        }       
154
155        @Override
156        public void acceptImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
157                super.acceptImpl(dialog, memoryMap);
158                Global.getSector().getListenerManager().addListener(this);
159        }
160
161        @Override
162        protected void notifyEnding() {
163                super.notifyEnding();
164                Global.getSector().getListenerManager().removeListener(this);
165        }
166        
167        @Override
168        public String getBaseName() {
169                return "Security Codes - " + faction.getDisplayName();
170        }
171        
172        public String getPostfixForState() {
173                if (isEnding()) {
174                        return " (Expired)";    
175                }
176                return "";
177        }
178        
179        @Override
180        protected String getMissionTypeNoun() {
181                return "Information";
182        }
183        
184        @Override
185        protected String getToCompleteText() {
186                return "remaining";
187        }
188        
189        
190        protected void checkCodesUsed(MarketAPI market) {
191                if (market.getFaction() == faction) {
192                        if (!isEnded() || isEnding()) {
193                                if (rollProbability(PROB_PATROL_ENCOUNTER_AFTER)) {
194                                        DelayedFleetEncounter e = new DelayedFleetEncounter(genRandom, getMissionId());
195                                        e.setDelayShort();
196                                        e.setLocationCoreOnly(true, faction.getId());
197                                        e.beginCreate();
198                                        e.triggerCreateFleet(FleetSize.LARGE, FleetQuality.DEFAULT, faction.getId(), FleetTypes.PATROL_LARGE, new Vector2f());
199                                        e.triggerSetAdjustStrengthBasedOnQuality(true, getQuality());
200                                        e.triggerSetPatrol();
201                                        e.triggerSetStandardAggroInterceptFlags();
202                                        e.triggerSetFleetMemoryValue("$seco_marketName", market.getName());
203                                        e.triggerSetFleetGenericHailPermanent("SECOPatrolHail");
204                                        e.endCreate();
205                                }
206                        }
207                        Global.getSector().getListenerManager().removeListener(this);
208                        endAfterDelay();
209                }
210        }
211        public void reportRaidToDisruptFinished(InteractionDialogAPI dialog,
212                        MarketAPI market, TempData actionData, Industry industry) {
213                checkCodesUsed(market);
214        }
215
216        public void reportRaidForValuablesFinishedBeforeCargoShown(InteractionDialogAPI dialog, 
217                        MarketAPI market, TempData actionData,
218                        CargoAPI cargo) {
219                checkCodesUsed(market);
220        }
221
222        public void reportSaturationBombardmentFinished(
223                        InteractionDialogAPI dialog, MarketAPI market, TempData actionData) {
224        }
225
226        public void reportTacticalBombardmentFinished(InteractionDialogAPI dialog,
227                        MarketAPI market, TempData actionData) {
228        }
229
230        public void modifyMarineLossesStatPreRaid(MarketAPI market, List<GroundRaidObjectivePlugin> objectives, MutableStat stat) {
231                if (market.getFaction() == faction) {
232                        stat.modifyMult("seco_mult", MARINE_LOSSES_MULT, "Security codes");
233                }
234        }
235}
236
237
238
239
240