001package com.fs.starfarer.api.impl.campaign.tutorial;
002
003import java.awt.Color;
004import java.util.List;
005import java.util.Map;
006import java.util.Random;
007import java.util.Set;
008
009import com.fs.starfarer.api.EveryFrameScript;
010import com.fs.starfarer.api.Global;
011import com.fs.starfarer.api.campaign.CampaignFleetAPI;
012import com.fs.starfarer.api.campaign.CargoAPI;
013import com.fs.starfarer.api.campaign.CommDirectoryEntryAPI;
014import com.fs.starfarer.api.campaign.CommDirectoryEntryAPI.EntryType;
015import com.fs.starfarer.api.campaign.FactionAPI;
016import com.fs.starfarer.api.campaign.InteractionDialogAPI;
017import com.fs.starfarer.api.campaign.PlanetAPI;
018import com.fs.starfarer.api.campaign.SectorEntityToken;
019import com.fs.starfarer.api.campaign.StarSystemAPI;
020import com.fs.starfarer.api.campaign.TextPanelAPI;
021import com.fs.starfarer.api.campaign.econ.MarketAPI;
022import com.fs.starfarer.api.campaign.rules.MemoryAPI;
023import com.fs.starfarer.api.characters.PersonAPI;
024import com.fs.starfarer.api.fleet.FleetMemberAPI;
025import com.fs.starfarer.api.fleet.FleetMemberType;
026import com.fs.starfarer.api.impl.campaign.JumpPointInteractionDialogPluginImpl;
027import com.fs.starfarer.api.impl.campaign.ids.Abilities;
028import com.fs.starfarer.api.impl.campaign.ids.Commodities;
029import com.fs.starfarer.api.impl.campaign.ids.Entities;
030import com.fs.starfarer.api.impl.campaign.ids.Factions;
031import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
032import com.fs.starfarer.api.impl.campaign.ids.Ranks;
033import com.fs.starfarer.api.impl.campaign.ids.Stats;
034import com.fs.starfarer.api.impl.campaign.ids.Submarkets;
035import com.fs.starfarer.api.impl.campaign.ids.Tags;
036import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
037import com.fs.starfarer.api.impl.campaign.intel.SystemBountyIntel;
038import com.fs.starfarer.api.impl.campaign.intel.SystemBountyManager;
039import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
040import com.fs.starfarer.api.impl.campaign.submarkets.StoragePlugin;
041import com.fs.starfarer.api.loading.WeaponSlotAPI;
042import com.fs.starfarer.api.ui.HintPanelAPI;
043import com.fs.starfarer.api.ui.SectorMapAPI;
044import com.fs.starfarer.api.ui.TooltipMakerAPI;
045import com.fs.starfarer.api.util.Misc;
046import com.fs.starfarer.api.util.Misc.Token;
047
048public class TutorialMissionIntel extends BaseIntelPlugin implements EveryFrameScript {
049        
050        public static final String TUT_STAGE = "$tutStage";
051        
052        public static final String REASON = "tut";
053        
054        public static enum TutorialMissionStage {
055                INIT,
056                GO_GET_DATA,
057                GOT_DATA,
058                GO_GET_AI_CORE,
059                GOT_AI_CORE,
060                GO_RECOVER_SHIPS,
061                RECOVERED_SHIPS,
062                GO_STABILIZE,
063                STABILIZED,
064                DELIVER_REPORT,
065                DONE,
066                ;
067        }
068        
069        protected float elapsedDays = 0;
070        
071        //protected TutorialMissionEventData data;
072        protected StarSystemAPI system;
073        protected PlanetAPI ancyra;
074        protected PlanetAPI pontus;
075        protected PlanetAPI tetra;
076        protected SectorEntityToken derinkuyu;
077        protected SectorEntityToken probe;
078        protected SectorEntityToken inner;
079        protected SectorEntityToken fringe;
080        protected SectorEntityToken detachment;
081        protected SectorEntityToken relay;
082        
083        protected PersonAPI mainContact;
084        protected PersonAPI dataContact;
085        protected PersonAPI jangalaContact;
086        protected PlanetAPI jangala;
087        
088        protected FactionAPI faction;
089        
090        protected TutorialMissionStage stage = TutorialMissionStage.INIT;
091        
092        /**
093         * Either this or the tutorial script. Returns false at the "deliver report to Jangala" stage.
094         * @return
095         */
096        public static boolean isTutorialInProgress() {
097                return Global.getSector().getMemoryWithoutUpdate().contains(CampaignTutorialScript.USE_TUTORIAL_RESPAWN);
098        }
099        
100        public TutorialMissionIntel() {
101                faction = Global.getSector().getFaction(Factions.HEGEMONY);
102                
103                system = Global.getSector().getStarSystem("galatia");
104                ancyra = (PlanetAPI) system.getEntityById("ancyra");
105                pontus = (PlanetAPI) system.getEntityById("pontus");
106                tetra = (PlanetAPI) system.getEntityById("tetra");
107                derinkuyu = system.getEntityById("derinkuyu_station");
108                probe = system.getEntityById("galatia_probe");
109                inner = system.getEntityById("galatia_jump_point_alpha");
110                fringe = system.getEntityById("galatia_jump_point_fringe");
111                detachment = system.getEntityById("tutorial_security_detachment");
112                relay = system.getEntityById("ancyra_relay");
113                
114                mainContact = createMainContact(ancyra);
115                
116                dataContact = Global.getSector().getFaction(Factions.INDEPENDENT).createRandomPerson(); 
117                dataContact.setRankId(Ranks.AGENT);
118                dataContact.setPostId(Ranks.POST_AGENT);
119                derinkuyu.getMarket().getCommDirectory().addPerson(dataContact);
120                
121//              String stageId = "start";
122//              Global.getSector().reportEventStage(this, stageId, Global.getSector().getPlayerFleet(), 
123//                                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(ancyra)); 
124
125                
126                mainContact.getMemoryWithoutUpdate().set("$tut_mainContact", true);
127                mainContact.getMemoryWithoutUpdate().set("$tut_eventRef", this);
128                Misc.makeImportant(mainContact, REASON);
129                
130                Global.getSector().getMemoryWithoutUpdate().set("$tut_jangalaContactName", mainContact.getNameString());
131                
132                updateStage(TutorialMissionStage.INIT, null);
133                
134                setImportant(true);
135                
136                Global.getSector().getIntelManager().addIntel(this);
137                Global.getSector().addScript(this);
138                //Global.getSector().getListenerManager().addListener(this);
139        }
140        
141        public static PersonAPI createMainContact(PlanetAPI ancyra) {
142                PersonAPI mainContact = ancyra.getFaction().createRandomPerson(); 
143                mainContact.setRankId(Ranks.CITIZEN);
144                mainContact.setPostId(Ranks.POST_STATION_COMMANDER);
145                ancyra.getMarket().getCommDirectory().addPerson(mainContact);
146                ancyra.getMarket().addPerson(mainContact);
147                
148                return mainContact;
149        }
150        
151        public static PersonAPI getJangalaContact() {
152                StarSystemAPI corvus = Global.getSector().getStarSystem("Corvus");
153                PlanetAPI jangala = (PlanetAPI) corvus.getEntityById("jangala");
154                
155                for (CommDirectoryEntryAPI entry : jangala.getMarket().getCommDirectory().getEntriesCopy()) {
156                        if (entry.getType() == EntryType.PERSON && entry.getEntryData() instanceof PersonAPI) {
157                                PersonAPI curr = (PersonAPI) entry.getEntryData();
158                                if (Ranks.POST_STATION_COMMANDER.equals(curr.getPostId())) {
159                                        return curr;
160                                }
161                        }
162                }
163                return null;
164        }
165        
166        public PersonAPI getMainContact() {
167                return mainContact;
168        }
169
170        protected void updateStage(TutorialMissionStage stage, TextPanelAPI text) {
171                this.stage = stage;
172                Global.getSector().getMemoryWithoutUpdate().set(TUT_STAGE, stage.name());
173                
174                if (stage != TutorialMissionStage.INIT) {
175                        //sendUpdateIfPlayerHasIntel(stage, false);
176                        sendUpdateIfPlayerHasIntel(stage, text);
177                }
178        }
179        
180        protected void endEvent() {
181                endAfterDelay();
182                Global.getSector().getMemoryWithoutUpdate().unset(TUT_STAGE);
183        }
184        
185        @Override
186        protected void notifyEnded() {
187                super.notifyEnded();
188                Global.getSector().removeScript(this);
189                //Global.getSector().getListenerManager().removeListener(this);
190        }
191
192        protected int preRecoverFleetSize = 2;
193        
194        @Override
195        protected void advanceImpl(float amount) {
196                float days = Global.getSector().getClock().convertToDays(amount);
197                
198                CampaignFleetAPI player = Global.getSector().getPlayerFleet();
199                if (player == null) return;
200                
201                //memory.advance(days);
202                elapsedDays += days;
203        
204                if (probe == null) probe = system.getEntityById("galatia_probe");
205                if (tetra == null) tetra = (PlanetAPI) system.getEntityById("tetra");
206                if (derinkuyu == null) derinkuyu = system.getEntityById("derinkuyu_station");
207                if (inner == null) inner = system.getEntityById("galatia_jump_point_alpha");
208                if (fringe == null) fringe = system.getEntityById("galatia_jump_point_fringe");
209                if (detachment == null) detachment = system.getEntityById("tutorial_security_detachment");
210                
211                if (stage == TutorialMissionStage.GO_GET_AI_CORE) {
212                        int cores = (int) player.getCargo().getCommodityQuantity(Commodities.GAMMA_CORE);
213                        float distToProbe = Misc.getDistance(player.getLocation(), probe.getLocation());
214                        if (cores > 0 && (!probe.isAlive() || distToProbe < 300)) {
215//                              Global.getSector().reportEventStage(this, "salvage_core_end", Global.getSector().getPlayerFleet(),
216//                                              MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(ancyra));
217                                Misc.makeImportant(mainContact, REASON);
218                                updateStage(TutorialMissionStage.GOT_AI_CORE, null);
219                        }
220                }
221                
222                if (stage == TutorialMissionStage.GO_RECOVER_SHIPS) {
223                        int count = 0;
224                        for (FleetMemberAPI member : player.getFleetData().getMembersListCopy()) {
225                                //if (member.getVariant().getHullSpec().isDHull()) count++;
226                                count++;
227                        }
228                        
229                        int wrecks = 0;
230                        for (SectorEntityToken entity : system.getEntitiesWithTag(Tags.SALVAGEABLE)) {
231                                String id = entity.getCustomEntityType();
232                                if (id == null) continue;
233                                if (Entities.WRECK.equals(id)) {
234                                        wrecks ++;
235                                }
236                        }
237                        
238                        if (count >= preRecoverFleetSize + 2 || wrecks < 3) {
239//                              Global.getSector().reportEventStage(this, "ship_recovery_end", Global.getSector().getPlayerFleet(),
240//                                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(ancyra));
241                                Misc.makeImportant(mainContact, REASON);
242                                Misc.makeUnimportant(tetra, REASON);
243                                updateStage(TutorialMissionStage.RECOVERED_SHIPS, null);
244                        }
245                }
246                
247                if (stage == TutorialMissionStage.GO_STABILIZE) {
248                        boolean innerStable = inner.getMemoryWithoutUpdate().getExpire(JumpPointInteractionDialogPluginImpl.UNSTABLE_KEY) > 0;
249                        boolean fringeStable = fringe.getMemoryWithoutUpdate().getExpire(JumpPointInteractionDialogPluginImpl.UNSTABLE_KEY) > 0;
250                        
251                        if (innerStable || fringeStable) {
252//                              Global.getSector().reportEventStage(this, "stabilize_jump_point_done", Global.getSector().getPlayerFleet(),
253//                                              MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(ancyra));
254                                Misc.makeImportant(mainContact, REASON);
255                                Misc.makeUnimportant(inner, REASON);
256                                updateStage(TutorialMissionStage.STABILIZED, null);
257                        }
258                        
259                }
260        
261        }
262
263        @Override
264        public boolean callEvent(String ruleId, final InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
265                String action = params.get(0).getString(memoryMap);
266                
267                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
268                CargoAPI cargo = playerFleet.getCargo();
269                
270                TextPanelAPI text = null;
271                if (dialog != null) text = dialog.getTextPanel();
272                
273                if (action.equals("startGetData")) {
274//                      Global.getSector().reportEventStage(this, "sneak_start", Global.getSector().getPlayerFleet(),
275//                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(derinkuyu));
276                        
277                        dataContact.getMemoryWithoutUpdate().set("$tut_dataContact", true);
278                        dataContact.getMemoryWithoutUpdate().set("$tut_eventRef", this);
279                        Misc.makeImportant(dataContact, REASON);
280                        Misc.makeUnimportant(mainContact, REASON);
281                        
282                        detachment.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PATROL_ALLOW_TOFF, true);
283                        
284                        updateStage(TutorialMissionStage.GO_GET_DATA, text);
285                        
286                        Global.getSector().getMemoryWithoutUpdate().set("$tutMadeContactAtAncyra", true);
287                        
288                        saveNag();
289                } else if (action.equals("endGetData")) {
290                        
291//                      Global.getSector().reportEventStage(this, "sneak_end", Global.getSector().getPlayerFleet(),
292//                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(ancyra));
293                        Misc.cleanUpMissionMemory(dataContact.getMemoryWithoutUpdate(), "tut_");
294                        
295                        Misc.makeUnimportant(dataContact, REASON);
296                        Misc.makeImportant(mainContact, REASON);
297                        
298                        updateStage(TutorialMissionStage.GOT_DATA, text);
299                        
300                } else if (action.equals("goSalvage")) {
301//                      Global.getSector().reportEventStage(this, "salvage_core_start", Global.getSector().getPlayerFleet(),
302//                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(pontus));
303                        Misc.makeUnimportant(mainContact, REASON);
304                        Misc.makeImportant(probe, REASON);
305                        
306                        updateStage(TutorialMissionStage.GO_GET_AI_CORE, text);
307                        
308                        saveNag();
309                } else if (action.equals("goRecover")) {
310//                      Global.getSector().reportEventStage(this, "ship_recovery_start", Global.getSector().getPlayerFleet(),
311//                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(tetra));
312                        Misc.makeUnimportant(mainContact, REASON);
313                        Misc.makeImportant(tetra, REASON);
314                        
315                        FleetMemberAPI member = Global.getFactory().createFleetMember(FleetMemberType.SHIP, "mudskipper_Standard");
316                        playerFleet.getFleetData().addFleetMember(member);
317                        AddRemoveCommodity.addFleetMemberGainText(member, dialog.getTextPanel());
318                        
319                        preRecoverFleetSize = playerFleet.getFleetData().getNumMembers();
320                        
321                        updateStage(TutorialMissionStage.GO_RECOVER_SHIPS, text);
322                } else if (action.equals("goStabilize")) {
323//                      Global.getSector().reportEventStage(this, "stabilize_jump_point", Global.getSector().getPlayerFleet(),
324//                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(inner));
325                        Misc.makeUnimportant(mainContact, REASON);
326                        Misc.makeImportant(inner, REASON);
327
328                        addWeaponsToStorage();
329                        
330                        inner.getMemoryWithoutUpdate().set(JumpPointInteractionDialogPluginImpl.CAN_STABILIZE, true);
331                        fringe.getMemoryWithoutUpdate().set(JumpPointInteractionDialogPluginImpl.CAN_STABILIZE, true);
332                        
333                        updateStage(TutorialMissionStage.GO_STABILIZE, text);
334                        
335                        saveNag();
336//              } else if (action.equals("addStipend")) {
337                } else if (action.equals("pickJangalaContact")) {
338                        
339                        StarSystemAPI corvus = Global.getSector().getStarSystem("Corvus");
340                        jangala = (PlanetAPI) corvus.getEntityById("jangala");
341                        
342                        jangalaContact = getJangalaContact();
343                        
344                        MemoryAPI mem = mainContact.getMemoryWithoutUpdate();
345                        mem.set("$jangalaContactPost", jangalaContact.getPost().toLowerCase(), 0);
346                        mem.set("$jangalaContactLastName", jangalaContact.getName().getLast(), 0);
347
348                        float distLY = Misc.getDistanceLY(playerFleet.getLocationInHyperspace(), jangala.getLocationInHyperspace());
349                        distLY += 4f;
350
351                        float fuel = playerFleet.getLogistics().getFuelCostPerLightYear() * distLY;
352                        fuel = (float) (Math.ceil(fuel / 10) * 10);
353                        mem.set("$jangalaFuel", (int) fuel);
354                } else if (action.equals("deliverReport")) {
355//                      Global.getSector().reportEventStage(this, "deliver_message", Global.getSector().getPlayerFleet(),
356//                                                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(jangala));
357                        
358                        Misc.makeUnimportant(mainContact, REASON);
359                        Misc.cleanUpMissionMemory(mainContact.getMemoryWithoutUpdate(), REASON + "_");
360                        Misc.makeUnimportant(inner, REASON);
361                        
362                        jangalaContact.getMemoryWithoutUpdate().set("$tut_jangalaContact", true);
363                        jangalaContact.getMemoryWithoutUpdate().set("$tut_eventRef", this);
364                        Misc.makeImportant(jangalaContact, REASON);
365                        
366                        updateStage(TutorialMissionStage.DELIVER_REPORT, text);
367                        
368                        endGalatiaPortionOfMission(true, true);
369                        
370                        Global.getSector().getMemoryWithoutUpdate().unset(CampaignTutorialScript.USE_TUTORIAL_RESPAWN);
371                        
372                } else if (action.equals("reportDelivered")) {
373//                      Global.getSector().reportEventStage(this, "end", Global.getSector().getPlayerFleet(),
374//                                      MessagePriority.DELIVER_IMMEDIATELY, createSetMessageLocationScript(jangala));
375                        
376                        Misc.makeUnimportant(jangalaContact, REASON);
377                        Misc.cleanUpMissionMemory(jangalaContact.getMemoryWithoutUpdate(), REASON + "_");
378                        
379                        updateStage(TutorialMissionStage.DONE, text);
380                        
381                        MarketAPI jangala = Global.getSector().getEconomy().getMarket("jangala");
382                        
383                        if (jangala != null) {
384                                SystemBountyManager.getInstance().addOrResetBounty(jangala);
385                        }
386                        
387                        endEvent();
388                } else if (action.equals("doRepairs")) {
389                        for (FleetMemberAPI member : playerFleet.getFleetData().getMembersListCopy()) {
390                                member.getRepairTracker().setMothballed(false);
391                                member.getStatus().repairFully();
392                                float max = member.getRepairTracker().getMaxCR();
393                                max = Math.max(max, .7f);
394                                float curr = member.getRepairTracker().getBaseCR();
395                                if (max > curr) {
396                                        member.getRepairTracker().applyCREvent(max - curr, "Repaired at dockyard");
397                                }
398                        }
399                } else if (action.equals("printRefitHint")) {
400                        String refit = Global.getSettings().getControlStringForEnumName("CORE_REFIT");
401                        String autofit = Global.getSettings().getControlStringForEnumName("REFIT_MANAGE_VARIANTS");
402                        String transponder = "";
403                        if (!playerFleet.isTransponderOn()) {
404                                transponder = "\n\nAlso: you'll need to re-dock with your transponder turned on to take advantage of Ancyra's facilities.";
405                        }
406                        dialog.getTextPanel().addPara("(Once this conversation is over, press %s to open the refit screen. " +
407                                        "After selecting a specific ship, you can press %s to %s - pick a desired loadout, " +
408                                        "and the ship will be automatically refitted to match it, using what weapons are available." + 
409                                        transponder + "",
410                                        Misc.getHighlightColor(), refit, autofit, "\"autofit\"");
411                        
412                        dialog.getTextPanel().addPara("In addition, you now have access to local storage at Ancyra, " +
413                                        "and some weapons and supplies have been placed there. To access it, click on the " +
414                                        "\"Storage\" button in the trade screen.)",
415                                        Misc.getHighlightColor(), refit, autofit, "\"Storage\"");
416                }
417                
418                return true;
419        }
420        
421        public static void endGalatiaPortionOfMission(boolean withStipend, boolean didTutorial) {
422        
423                if (withStipend) {
424                        new GalatianAcademyStipend();
425                }
426                
427                StarSystemAPI system = Global.getSector().getStarSystem("galatia");
428                PlanetAPI ancyra = (PlanetAPI) system.getEntityById("ancyra");
429                PlanetAPI pontus = (PlanetAPI) system.getEntityById("pontus");
430                PlanetAPI tetra = (PlanetAPI) system.getEntityById("tetra");
431                SectorEntityToken derinkuyu = system.getEntityById("derinkuyu_station");
432                SectorEntityToken probe = system.getEntityById("galatia_probe");
433                SectorEntityToken inner = system.getEntityById("galatia_jump_point_alpha");
434                SectorEntityToken fringe = system.getEntityById("galatia_jump_point_fringe");
435                SectorEntityToken relay = system.getEntityById("ancyra_relay");
436                
437                relay.getMemoryWithoutUpdate().unset(MemFlags.OBJECTIVE_NON_FUNCTIONAL);
438                
439                Global.getSector().getCharacterData().addAbility(Abilities.TRANSPONDER);
440                Global.getSector().getCharacterData().addAbility(Abilities.GO_DARK);
441                Global.getSector().getCharacterData().addAbility(Abilities.SENSOR_BURST);
442                Global.getSector().getCharacterData().addAbility(Abilities.EMERGENCY_BURN);
443                Global.getSector().getCharacterData().addAbility(Abilities.SUSTAINED_BURN);
444                Global.getSector().getCharacterData().addAbility(Abilities.SCAVENGE);
445                Global.getSector().getCharacterData().addAbility(Abilities.INTERDICTION_PULSE);
446                Global.getSector().getCharacterData().addAbility(Abilities.DISTRESS_CALL);
447                
448                FactionAPI hegemony = Global.getSector().getFaction(Factions.HEGEMONY);
449                if (hegemony.getRelToPlayer().getRel() < 0) {
450                        hegemony.getRelToPlayer().setRel(0);
451                }
452                
453                // removing this leaves "supplement from local resources" bonuses active
454                //ancyra.getMarket().removeSubmarket(Submarkets.LOCAL_RESOURCES);
455                
456                Global.getSector().getEconomy().addMarket(ancyra.getMarket(), false);
457                Global.getSector().getEconomy().addMarket(derinkuyu.getMarket(), false);
458                
459                HintPanelAPI hints = Global.getSector().getCampaignUI().getHintPanel();
460                if (hints != null) {
461                        hints.clearHints(false);
462                }
463                
464                if (!SystemBountyManager.getInstance().isActive(ancyra.getMarket())) {
465                        SystemBountyManager.getInstance().addActive(new SystemBountyIntel(ancyra.getMarket()));
466                }
467//              CampaignEventManagerAPI eventManager = Global.getSector().getEventManager();
468//              eventManager.startEvent(new CampaignEventTarget(ancyra.getMarket()), Events.SYSTEM_BOUNTY, null);
469                
470                RogueMinerMiscFleetManager script = new RogueMinerMiscFleetManager(derinkuyu);
471                for (int i = 0; i < 20; i++) {
472                        script.advance(1f);
473                }
474                system.addScript(script);
475                
476                for (CampaignFleetAPI fleet : system.getFleets()) {
477                        if (Factions.PIRATES.equals(fleet.getFaction().getId())) {
478                                fleet.removeScriptsOfClass(TutorialLeashAssignmentAI.class);
479                        }
480                }
481                
482                inner.getMemoryWithoutUpdate().unset(JumpPointInteractionDialogPluginImpl.UNSTABLE_KEY);
483                inner.getMemoryWithoutUpdate().unset(JumpPointInteractionDialogPluginImpl.CAN_STABILIZE);
484                
485                fringe.getMemoryWithoutUpdate().unset(JumpPointInteractionDialogPluginImpl.UNSTABLE_KEY);
486                fringe.getMemoryWithoutUpdate().unset(JumpPointInteractionDialogPluginImpl.CAN_STABILIZE);
487                
488                system.removeTag(Tags.SYSTEM_CUT_OFF_FROM_HYPER);
489                
490                MarketAPI market = ancyra.getMarket();
491                market.getMemoryWithoutUpdate().unset(MemFlags.MARKET_DO_NOT_INIT_COMM_LISTINGS);
492                market.getStats().getDynamic().getMod(Stats.PATROL_NUM_LIGHT_MOD).unmodifyMult("tut");
493                market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).unmodifyMult("tut");
494                market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).unmodifyMult("tut");
495                market.setEconGroup(null);
496                
497                derinkuyu.getMarket().setEconGroup(null);
498                
499//              if (didTutorial) {
500//                      Global.getSector().getMemoryWithoutUpdate().set("$sti");
501//              }
502        }
503        
504        
505        
506        
507        protected void saveNag() {
508                if (!Global.getSector().hasScript(SaveNagScript.class)) {
509                        Global.getSector().addScript(new SaveNagScript(10f));
510                }
511        }
512        
513        
514        public void addWeaponsToStorage() {
515                StoragePlugin plugin = ((StoragePlugin)ancyra.getMarket().getSubmarket(Submarkets.SUBMARKET_STORAGE).getPlugin());
516                plugin.setPlayerPaidToUnlock(true);
517                
518                CargoAPI cargo = plugin.getCargo();
519                
520                CampaignFleetAPI player = Global.getSector().getPlayerFleet();
521                for (FleetMemberAPI member : player.getFleetData().getMembersListCopy()) {
522                        if (!member.getVariant().hasTag(Tags.SHIP_RECOVERABLE)) continue;
523                        
524                        //if (member.getVariant().getHullSpec().isDHull()) {
525                                for (WeaponSlotAPI slot : member.getVariant().getHullSpec().getAllWeaponSlotsCopy()) {
526                                        //if (member.getVariant().getWeaponId(slot.getId()) == null) {
527                                                String weaponId = getWeaponForSlot(slot);
528                                                if (weaponId != null) {
529                                                        cargo.addWeapons(weaponId, 1);
530                                                }
531                                        //}
532                                }
533                        //}
534                }
535                
536                cargo.addFighters("broadsword_wing", 1);
537                cargo.addFighters("piranha_wing", 1);
538                
539                cargo.addSupplies(100);
540                cargo.sort();
541        }
542        
543        public String getWeaponForSlot(WeaponSlotAPI slot) {
544                switch (slot.getWeaponType()) {
545                case BALLISTIC:
546                case COMPOSITE:
547                case HYBRID:
548                case UNIVERSAL:
549                        switch (slot.getSlotSize()) {
550                        case LARGE: return pick("mark9", "hephag", "hellbore");
551                        case MEDIUM: return pick("arbalest", "heavymortar", "shredder");
552                        case SMALL: return pick("lightmg", "lightac", "lightmortar");
553                        }
554                        break;
555                case MISSILE:
556                case SYNERGY:
557                        switch (slot.getSlotSize()) {
558                        case LARGE: return pick("hammerrack");
559                        case MEDIUM: return pick("pilum", "annihilatorpod");
560                        case SMALL: return pick("harpoon", "sabot", "annihilator");
561                        }
562                        break;
563                case ENERGY:
564                        switch (slot.getSlotSize()) {
565                        case LARGE: return pick("autopulse", "hil");
566                        case MEDIUM: return pick("miningblaster", "gravitonbeam", "pulselaser");
567                        case SMALL: return pick("mininglaser", "taclaser", "pdlaser", "ioncannon");
568                        }
569                        break;
570                }
571                
572        
573                return null;
574        }
575        
576        public String pick(String ...strings) {
577                return strings[new Random().nextInt(strings.length)];
578        }
579        
580        
581        public void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode) {
582                Color h = Misc.getHighlightColor();
583                Color g = Misc.getGrayColor();
584                Color c = getTitleColor(mode);
585                Color tc = Misc.getTextColor();
586                float pad = 3f;
587                float opad = 10f;
588                
589                info.setParaSmallInsignia();
590                info.addPara(getName(), c, 0f);
591                info.setParaFontDefault();
592
593                addBulletPoints(info, mode);
594        }
595                
596        protected void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode) {
597                Color h = Misc.getHighlightColor();
598                Color g = Misc.getGrayColor();
599                Color c = getTitleColor(mode);
600                
601                float opad = 10f;
602                
603                float pad = 3f;
604                if (mode == ListInfoMode.IN_DESC) pad = 10f;
605                
606                Color tc = getBulletColorForMode(mode);
607                
608                bullet(info);
609                
610                switch (stage) {
611                case INIT:
612                        info.addPara("Contact " + getMainContactPostName() + " at Ancyra", tc, pad);
613                        break;
614                case GO_GET_DATA:
615                        info.addPara("Sneak into " + derinkuyu.getName(), tc, pad);
616                        info.addPara("Contact " + dataContact.getNameString() + " and retrieve data", tc, 0f);
617                        break;
618                case GOT_DATA:
619                        info.addPara("Deliver data to " + getMainContactPostName() + " at Ancyra", tc, pad);
620                        break;
621                case GO_GET_AI_CORE:
622                        info.addPara("Retrieve AI core from derelict probe beyond the orbit of Pontus", tc, pad);
623                        break;
624                case GOT_AI_CORE:
625                        info.addPara("Deliver AI core to " + getMainContactPostName() + " at Ancyra", tc, pad);
626                        break;
627                case GO_RECOVER_SHIPS:
628                        info.addPara("Recover at least %s ships at Tetra", pad, tc, h, "" + 2);
629                        break;
630                case RECOVERED_SHIPS:
631                        info.addPara("Return to " + getMainContactPostName() + " with the ships", tc, pad);
632                        break;
633                case GO_STABILIZE:
634                        info.addPara("Stabilize the inner-system jump-point", tc, pad);
635                        break;
636                case STABILIZED:
637                        info.addPara("Return to Ancyra and report your success", tc, pad);
638                        break;
639                case DELIVER_REPORT:
640                        info.addPara("Deliver report to " + getJangalaContactPostName() + " at Jangala", tc, pad);
641                        break;
642                case DONE:
643                        info.addPara("Completed", tc, pad);
644                        break;
645                }
646                
647                unindent(info);
648        }
649        
650        public String getName() {
651                return "Stabilize the Jump-points";
652        }
653        
654        
655        @Override
656        public FactionAPI getFactionForUIColors() {
657                return faction;
658        }
659
660        protected String getMainContactPostName() {
661                return mainContact.getPost() + " " + mainContact.getNameString();
662        }
663        protected String getJangalaContactPostName() {
664                return jangalaContact.getPost() + " " + jangalaContact.getNameString();
665        }
666        
667        public String getSmallDescriptionTitle() {
668                return getName();
669        }
670        
671        public void createSmallDescription(TooltipMakerAPI info, float width, float height) {
672                Color h = Misc.getHighlightColor();
673                Color g = Misc.getGrayColor();
674                Color tc = Misc.getTextColor();
675                float pad = 3f;
676                float opad = 10f;
677                
678                //info.addImage(dataContact.getFaction().getLogo(), width, 256 / 1.6f, opad);
679
680                boolean addedBullets = false;
681                switch (stage) {
682                case INIT:
683                        info.addPara("You receive a tight-beam communication from the system's main inhabited world, Ancyra.", opad);
684                        
685                        info.addPara("The message is brief and asks you to travel there and contact " +
686                                                 getMainContactPostName() + " as soon as possible.", opad);
687                        break;
688                case GO_GET_DATA:
689                        info.addPara("Contact " + dataContact.getNameString() + " at Derinkuyu Mining Station " +
690                                        "to acquire the raw jump-point readings.", opad);
691                        
692                        info.addPara("Contact must be made with the transponder off as the miners of Derinkuyu have " +
693                                        "turned pirate and your fleet will be attacked otherwise.", opad);
694
695//                      addBulletPoints(info, true, tc);
696//                      addedBullets = true;
697                        
698                        info.addPara("Use %s to avoid detection, and %s to get away if you are seen.", opad, h,
699                                        "Go Dark", "Emergency Burn");
700                        break;
701                case GOT_DATA:
702                        info.addPara("Return to Ancyra and contact " + getMainContactPostName() + 
703                                                 " to deliver the jump-point data.", opad);
704                        break;
705                case GO_GET_AI_CORE:
706                        info.addPara("Analyzing the jump-point data requires an AI Core.", opad);
707
708                        info.addPara("There's a Domain-era survey probe outside the orbit of Pontus. If salvaged, " +
709                                                 "it's likely to yield a gamma AI core, which should be sufficient for the task.", opad);
710                        
711                        info.addPara("Go to Pontus, head out towards the asteroid belt, and then use an " +
712                                                 "%s to locate the probe. ", opad, h, "Active Sensor Burst");
713
714                        info.addPara("Approach the probe and salvage it to recover the gamma core.", opad);
715
716                        info.addPara("It's likely that you will have to overcome some automated defenses first.", opad);
717                        break;
718                case GOT_AI_CORE:
719                        info.addPara("Return to Ancyra and contact " + getMainContactPostName() + 
720                                                 " to deliver the AI core.", opad);
721                        break;
722                case GO_RECOVER_SHIPS:
723                        info.addPara("Go to the ship graveyard around Tetra and recover as many ships as possible.", opad);
724
725                        info.addPara("Bring extra crew to man the recovered ships, and extra supplies to " +
726                                                 " help restore their combat readiness.", opad);
727                        break;
728                case RECOVERED_SHIPS:
729                        info.addPara("Return to " + getMainContactPostName() + 
730                                                 " at Ancyra for help with outfitting the recovered ships with weapons.", opad);
731                        break;
732                case GO_STABILIZE:
733                        info.addPara("Use the hyperwave sequence produced by the AI core " +
734                                        "to stabilize the inner-system jump-point.", opad);
735
736                        info.addPara("You will have to defeat the pirates guarding it first.", opad);
737                        break;
738                case STABILIZED:
739                        info.addPara("Galatia's connection with hyperspace has been restored, " +
740                                        "and trade fleets are once again able to enter and leave the system.", opad);
741
742                        info.addPara("The Derinkuyu leadership will surely soon be toppled by rank-and-file " +
743                                                 "miners eager to get on the right side of the law once again.", opad);
744                        break;
745                case DELIVER_REPORT:
746                        info.addPara(Misc.ucFirst(getMainContactPostName()) + " has tasked you with delivering a report " +
747                                        "detailing the recent events to the " + getJangalaContactPostName() + " at Jangala.", opad);
748
749                        info.addPara("Make sure you have enough fuel to make the trip successfully.", opad);
750                        break;
751                case DONE:
752                        info.addPara("You have delivered the report and " +
753                                                 "your standing with the Hegemony has increased substantially.", opad);
754                        
755                        info.addPara("Galatia's connection with hyperspace has been restored, " +
756                                                 "and trade fleets are once again able to enter and leave the system.", opad);
757                        break;
758                }
759                
760//              if (!addedBullets) {
761//                      addBulletPoints(info, true, tc);
762//              }
763                
764        }
765        
766        public String getIcon() {
767                return Global.getSettings().getSpriteName("campaignMissions", "tutorial");
768        }
769        
770
771        public Set<String> getIntelTags(SectorMapAPI map) {
772                Set<String> tags = super.getIntelTags(map);
773                tags.add(Tags.INTEL_STORY);
774                tags.add(Factions.HEGEMONY);
775                return tags;
776        }
777
778        @Override
779        public String getCommMessageSound() {
780                if (isSendingUpdate()) {
781                        return getSoundStandardUpdate();
782                }
783                return getSoundMajorPosting();
784        }
785        
786
787        @Override
788        public SectorEntityToken getMapLocation(SectorMapAPI map) {
789                switch (stage) {
790                case INIT: return ancyra;
791                case GO_GET_DATA: return derinkuyu;
792                case GOT_DATA: return ancyra;
793                case GO_GET_AI_CORE: return pontus;
794                case GOT_AI_CORE: return ancyra;
795                case GO_RECOVER_SHIPS: return tetra;
796                case RECOVERED_SHIPS: return ancyra;
797                case GO_STABILIZE: return inner;
798                case STABILIZED: return ancyra;
799                case DELIVER_REPORT: return jangala;
800                case DONE: return ancyra;
801                }
802                
803                return ancyra;
804        }
805
806                
807        
808        @Override
809        public boolean canTurnImportantOff() {
810                return isEnding();
811        }
812
813        @Override
814        public IntelSortTier getSortTier() {
815                return IntelSortTier.TIER_2;
816        }
817        
818        @Override
819        public String getSortString() {
820                return getName();
821        }
822        
823
824        public boolean runWhilePaused() {
825                return false;
826        }
827
828        
829        @Override
830        public boolean isHidden() {
831                return false;
832        }
833        
834        
835}
836
837
838