001package com.fs.starfarer.api.impl.campaign.intel.events.ttcr;
002
003import java.awt.Color;
004import java.util.EnumSet;
005import java.util.Random;
006import java.util.Set;
007
008import org.lwjgl.util.vector.Vector2f;
009
010import com.fs.starfarer.api.Global;
011import com.fs.starfarer.api.campaign.FactionAPI;
012import com.fs.starfarer.api.campaign.InteractionDialogAPI;
013import com.fs.starfarer.api.campaign.TextPanelAPI;
014import com.fs.starfarer.api.impl.campaign.ids.Factions;
015import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
016import com.fs.starfarer.api.impl.campaign.ids.Skills;
017import com.fs.starfarer.api.impl.campaign.ids.Tags;
018import com.fs.starfarer.api.impl.campaign.intel.events.BaseEventIntel;
019import com.fs.starfarer.api.impl.campaign.intel.events.BaseFactorTooltip;
020import com.fs.starfarer.api.impl.campaign.intel.events.EventFactor;
021import com.fs.starfarer.api.impl.campaign.intel.events.TriTachyonHostileActivityFactor;
022import com.fs.starfarer.api.impl.campaign.missions.DelayedFleetEncounter;
023import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality;
024import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetSize;
025import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerNum;
026import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerQuality;
027import com.fs.starfarer.api.ui.LabelAPI;
028import com.fs.starfarer.api.ui.SectorMapAPI;
029import com.fs.starfarer.api.ui.TooltipMakerAPI;
030import com.fs.starfarer.api.ui.TooltipMakerAPI.TooltipCreator;
031import com.fs.starfarer.api.util.Misc;
032import com.fs.starfarer.api.util.WeightedRandomPicker;
033
034public class TriTachyonCommerceRaiding extends BaseEventIntel {
035        
036        public static int PROGRESS_MAX = 300;
037        public static int PROGRESS_1 = 150;
038        
039        public static String KEY = "$ttcr_ref";
040        
041        public static enum Stage {
042                START,
043                SEND_MERC,
044                SUCCESS,
045        }
046        
047
048        public static void addFactorCreateIfNecessary(EventFactor factor, InteractionDialogAPI dialog) {
049                if (get() == null) {
050                        new TriTachyonCommerceRaiding(null, false);
051                }
052                if (get() != null) {
053                        get().addFactor(factor, dialog);
054                }
055        }
056        
057        public static TriTachyonCommerceRaiding get() {
058                return (TriTachyonCommerceRaiding) Global.getSector().getMemoryWithoutUpdate().get(KEY);
059        }
060        
061        
062        public TriTachyonCommerceRaiding(TextPanelAPI text, boolean withIntelNotification) {
063                super();
064                
065                Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
066                
067                setup();
068                
069                // now that the event is fully constructed, add it and send notification
070                Global.getSector().getIntelManager().addIntel(this, !withIntelNotification, text);
071        }
072        
073        protected void setup() {
074                factors.clear();
075                stages.clear();
076                
077                setMaxProgress(PROGRESS_MAX);
078                
079                addStage(Stage.START, 0);
080                addStage(Stage.SEND_MERC, PROGRESS_1, true, StageIconSize.MEDIUM);
081                addStage(Stage.SUCCESS, PROGRESS_MAX, true, StageIconSize.LARGE);
082                
083                // not actualy repeatable since no way to reduce progress
084                // but this will keep the icon and the stage description showing
085                //getDataFor(Stage.SEND_MERC).isRepeatable = false;
086                
087                addFactor(new TTCRCommerceRaidersDestroyedFactorHint());
088                addFactor(new TTCRTradeFleetsDestroyedFactorHint());
089                addFactor(new TTCRIndustryDisruptedFactorHint());
090                
091        }
092        
093        protected Object readResolve() {
094                return this;
095        }
096        
097        
098        @Override
099        protected void notifyEnding() {
100                super.notifyEnding();
101        }
102
103        @Override
104        protected void notifyEnded() {
105                super.notifyEnded();
106                Global.getSector().getMemoryWithoutUpdate().unset(KEY);
107        }
108        
109        protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode, boolean isUpdate, 
110                                                                        Color tc, float initPad) {
111                
112                if (addEventFactorBulletPoints(info, mode, isUpdate, tc, initPad)) {
113                        return;
114                }
115                
116                Color h = Misc.getHighlightColor();
117                if (isUpdate && getListInfoParam() instanceof EventStageData) {
118                        EventStageData esd = (EventStageData) getListInfoParam();
119                        if (esd.id == Stage.SEND_MERC) {
120                                info.addPara("Several bounty hunters were recently hired to eliminate you", tc, initPad);
121                        }
122                        if (esd.id == Stage.SUCCESS) {
123                                info.addPara("You've convincied Tri-Tachyon to stop attacking your interests", tc, initPad);
124                        }
125                        return;
126                }
127                
128        }
129        
130        @Override
131        public void addStageDescriptionText(TooltipMakerAPI info, float width, Object stageId) {
132                float opad = 10f;
133                float small = 0f;
134                Color h = Misc.getHighlightColor();
135                
136                //setProgress(0);
137                //setProgress(199);
138                //setProgress(600);
139                //setProgress(899);
140                //setProgress(1000);
141                //setProgress(499);
142                //setProgress(600);
143                
144                EventStageData stage = getDataFor(stageId);
145                if (stage == null) return;
146                
147                if (isStageActive(stageId)) {
148                        addStageDesc(info, stageId, small, false);
149                }
150        }
151        
152        public FactionAPI getFaction() {
153                return Global.getSector().getFaction(Factions.TRITACHYON);
154        }
155        
156        
157        public void addStageDesc(TooltipMakerAPI info, Object stageId, float initPad, boolean forTooltip) {
158                float opad = 10f;
159                Color h = Misc.getHighlightColor();
160                
161                FactionAPI faction = getFaction();
162                Color tt = faction.getBaseUIColor();
163                
164                if (stageId == Stage.START) {
165                        LabelAPI label = info.addPara("The %s needs to be convinced that continued investment in "
166                                        + "acting against your interests is unprofitable in the long term. If you are "
167                                        + "able to send this message without becoming openly hostile - or smooth any ruffled feathers "
168                                        + "afterwards - this may even "
169                                        + "mark you as someone whose understanding of business realities makes them worth working with.",
170                                        initPad, tt, faction.getDisplayNameLong());
171                        label.setHighlight(faction.getDisplayNameLong(), "worth working with");
172                        label.setHighlightColors(tt,
173                                        Misc.getPositiveHighlightColor());
174                } else if (stageId == Stage.SUCCESS) {
175                        info.addPara("You've convinced the %s to stop attacking your interests.", initPad,
176                                        tt, faction.getDisplayNameLong());
177                } else if (stageId == Stage.SEND_MERC) {
178                        info.addPara("Several bounty hunters were recently hired to eliminate you. You are likely "
179                                        + "to encounter them in the coming months. Resolving the matter with Tri-Tachyon before then "
180                                        + "is unlikely to make a difference in this; a contract is a contract.", initPad);
181                }
182        }
183        
184        public TooltipCreator getStageTooltipImpl(Object stageId) {
185                final EventStageData esd = getDataFor(stageId);
186                
187                if (esd != null && EnumSet.of(Stage.SEND_MERC, Stage.SUCCESS).contains(esd.id)) {
188                        return new BaseFactorTooltip() {
189                                @Override
190                                public void createTooltip(TooltipMakerAPI tooltip, boolean expanded, Object tooltipParam) {
191                                        float opad = 10f;
192                                        
193                                        if (esd.id == Stage.SEND_MERC) {
194                                                tooltip.addTitle("Bounty posted");
195                                        } else if (esd.id == Stage.SUCCESS) {
196                                                tooltip.addTitle("Success!");
197                                        }
198
199                                        addStageDesc(tooltip, esd.id, opad, true);
200                                        
201                                        esd.addProgressReq(tooltip, opad);
202                                }
203                        };
204                }
205                
206                return null;
207        }
208
209
210
211        @Override
212        public String getIcon() {
213                return Global.getSettings().getSpriteName("events", "triTachyonCR_START");
214        }
215
216        protected String getStageIconImpl(Object stageId) {
217                EventStageData esd = getDataFor(stageId);
218                if (esd == null) return null;
219                
220                return Global.getSettings().getSpriteName("events", "triTachyonCR_" + ((Stage)esd.id).name());
221        }
222        
223        
224        @Override
225        public Set<String> getIntelTags(SectorMapAPI map) {
226                Set<String> tags = super.getIntelTags(map);
227                tags.add(Tags.INTEL_COLONIES);
228                tags.add(Factions.TRITACHYON);
229                return tags;
230        }
231
232        @Override
233        public Color getBarColor() {
234                Color color = getFaction().getBaseUIColor();
235                color = Misc.interpolateColor(color, Color.black, 0.25f);
236                return color;
237        }
238        
239        @Override
240        public Color getBarProgressIndicatorColor() {
241                return super.getBarProgressIndicatorColor();
242        }
243
244        @Override
245        protected int getStageImportance(Object stageId) {
246                return super.getStageImportance(stageId);
247        }
248
249
250        @Override
251        protected String getName() {
252                return "Tri-Tachyon Commerce Raiding";
253        }
254        
255
256
257        @Override
258        protected void advanceImpl(float amount) {
259                super.advanceImpl(amount);
260                
261                //setProgress(500);
262                //float days = Global.getSector().getClock().convertToDays(amount);
263        }
264        
265        
266        @Override
267        protected void notifyStageReached(EventStageData stage) {
268                //applyFleetEffects();
269                
270                if (stage.id == Stage.SEND_MERC) {
271                        sendBountyHunters();
272                }
273
274                if (stage.id == Stage.SUCCESS) {
275                        TriTachyonHostileActivityFactor.setPlayerCounterRaidedTriTach();
276                        endAfterDelay();
277                }
278        }
279
280        public boolean withMonthlyFactors() {
281                return false;
282        }
283        
284        protected String getSoundForStageReachedUpdate(Object stageId) {
285//              if (stageId == Stage.SEND_MERC) {
286//                      return "ui_learned_ability";
287//              }
288                return super.getSoundForStageReachedUpdate(stageId);
289        }
290
291        @Override
292        protected String getSoundForOneTimeFactorUpdate(EventFactor factor) {
293                return null;
294        }
295        
296        protected void sendBountyHunters() {
297                // wolfpack
298                {
299                        Random r = Misc.getRandom(random.nextLong(), 7);
300                        DelayedFleetEncounter e = new DelayedFleetEncounter(r, "TTCRBountyHunterWolfpack");
301                        e.setDelayVeryShort();
302                        //e.setDelayNone();
303                        e.setDoNotAbortWhenPlayerFleetTooStrong(); // small ships, few FP, but a strong fleet
304                        e.setLocationOuterSector(true, Factions.INDEPENDENT);
305                        e.beginCreate();
306                        e.triggerCreateFleet(FleetSize.LARGE, FleetQuality.SMOD_3, Factions.MERCENARY, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f());
307                        e.triggerSetFleetMaxShipSize(1);
308                        e.triggerSetFleetDoctrineOther(5, 4);
309                        
310                        
311                        WeightedRandomPicker<String> picker = new WeightedRandomPicker<String>(r);
312                        picker.add("tempest_Attack", 10);
313                        picker.add("tempest_Attack", 10);
314                        picker.add("tempest_Attack", 10);
315                        picker.add("scarab_Experimental", 10);
316                        picker.add("scarab_Experimental", 10);
317                        picker.add("scarab_Experimental", 10);
318                        picker.add("hyperion_Attack", 10);
319                        picker.add("hyperion_Strike", 10);
320                        picker.add("omen_PD", 5);
321                        picker.add("omen_PD", 5);
322                        picker.add("monitor_Escort", 5);
323                        picker.add("monitor_Escort", 5);
324                        picker.add("shade_Assault", 5);
325                        picker.add("shade_Assault", 5);
326                        picker.add("afflictor_Strike", 5);
327                        picker.add("afflictor_Strike", 5);
328                        
329//                      for (ShipHullSpecAPI spec : Global.getSettings().getAllShipHullSpecs()) {
330//                              if (spec.hasTag("merc") && spec.hasTag("wolfpack")) {
331//                                      List<String> variants = Global.getSettings().getHullIdToVariantListMap().get(spec.getHullId());
332//                                      for (String variantId : variants) {
333//                                              ShipVariantAPI v = Global.getSettings().getVariant(variantId);
334//                                              if (v.isGoalVariant() && v.isStockVariant()) {
335//                                                      picker.add(variantId);
336//                                              }
337//                                      }
338//                              }
339//                      }
340                        
341                        int add = 9;
342                        while (!picker.isEmpty() && add > 0) {
343                                e.triggerAddShips(picker.pickAndRemove());
344                                add--;
345                        }
346                        
347                        
348                
349                        e.triggerSetFleetMaxNumShips(14);
350                        e.triggerSetFleetDoctrineComp(5, 0, 0);
351                
352                        e.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1);
353                        e.triggerFleetAddCommanderSkill(Skills.WOLFPACK_TACTICS, 1);
354                        e.triggerFleetAddCommanderSkill(Skills.ELECTRONIC_WARFARE, 1);
355                        e.triggerFleetAddCommanderSkill(Skills.FLUX_REGULATION, 1);
356                        e.triggerFleetAddCommanderSkill(Skills.TACTICAL_DRILLS, 1);
357                        e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.UNUSUALLY_HIGH);
358                        
359                        e.triggerFleetMakeFaster(true, 0, true);
360                        
361                        e.triggerSetFleetFaction(Factions.INDEPENDENT);
362                        e.triggerMakeNoRepImpact();
363                        e.triggerSetStandardAggroInterceptFlags();
364                        e.triggerMakeFleetIgnoreOtherFleets();
365                        e.triggerSetFleetGenericHailPermanent("TTCRBountyHunterHail");
366                        e.triggerSetFleetFlagPermanent("$ttcr_wolfpack");
367                        e.endCreate();
368                }
369                
370                // phase
371                {
372                        Random r = Misc.getRandom(random.nextLong(), 3);
373                        DelayedFleetEncounter e = new DelayedFleetEncounter(r, "TTCRBountyHunterPhase");
374                        e.setDelayVeryShort();
375                        //e.setDelayNone();
376                        e.setLocationInnerSector(true, Factions.INDEPENDENT);
377                        e.beginCreate();
378                        e.triggerCreateFleet(FleetSize.LARGE, FleetQuality.SMOD_3, Factions.MERCENARY, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f());
379                        
380                        e.triggerSetFleetDoctrineComp(0, 0, 5);
381                
382                        e.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1);
383                        e.triggerFleetAddCommanderSkill(Skills.PHASE_CORPS, 1);
384                        e.triggerFleetAddCommanderSkill(Skills.ELECTRONIC_WARFARE, 1);
385                        e.triggerFleetAddCommanderSkill(Skills.FLUX_REGULATION, 1);
386                        e.triggerFleetAddCommanderSkill(Skills.TACTICAL_DRILLS, 1);
387                        e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER);
388                        
389                        e.triggerFleetMakeFaster(true, 0, true);
390                        
391                        e.triggerSetFleetFaction(Factions.INDEPENDENT);
392                        e.triggerMakeNoRepImpact();
393                        e.triggerSetStandardAggroInterceptFlags();
394                        e.triggerMakeFleetIgnoreOtherFleets();
395                        e.triggerSetFleetGenericHailPermanent("TTCRBountyHunterHail");
396                        e.triggerSetFleetFlagPermanent("$ttcr_phase");
397                        e.endCreate();
398                }
399                
400                
401                // derelict
402                {
403                        Random r = Misc.getRandom(random.nextLong(), 11);
404                        DelayedFleetEncounter e = new DelayedFleetEncounter(r, "TTCRBountyHunterDerelict");
405                        e.setDelayVeryShort();
406                        //e.setDelayNone();
407                        //e.setLocationCoreOnly(true, market.getFactionId());
408                        e.setLocationCoreOnly(true, Factions.INDEPENDENT);
409                        e.beginCreate();
410                        e.triggerCreateFleet(FleetSize.HUGE, FleetQuality.VERY_LOW, Factions.LUDDIC_CHURCH, FleetTypes.MERC_BOUNTY_HUNTER, new Vector2f());
411                        
412                        //e.triggerSetFleetDoctrineComp(4, 2, 1);
413                        e.triggerSetFleetDoctrineOther(5, 5);
414                
415                        e.triggerFleetAddCommanderSkill(Skills.DERELICT_CONTINGENT, 1);
416                        e.triggerFleetAddCommanderSkill(Skills.SUPPORT_DOCTRINE, 1);
417                        e.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1);
418                        e.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.LOWER);
419                        
420                        e.triggerFleetMakeFaster(true, 2, true);
421                        
422                        e.triggerSetFleetFaction(Factions.INDEPENDENT);
423                        e.triggerMakeNoRepImpact();
424                        e.triggerSetStandardAggroInterceptFlags();
425                        e.triggerMakeFleetIgnoreOtherFleets();
426                        e.triggerSetFleetGenericHailPermanent("TTCRBountyHunterHail");
427                        e.triggerSetFleetFlagPermanent("$ttcr_derelict");
428                        e.endCreate();
429                }
430                
431        }
432        
433}
434
435
436
437
438
439
440
441