001package com.fs.starfarer.api.impl.campaign.tutorial;
002
003import org.lwjgl.util.vector.Vector2f;
004
005import com.fs.starfarer.api.EveryFrameScript;
006import com.fs.starfarer.api.Global;
007import com.fs.starfarer.api.campaign.CampaignFleetAPI;
008import com.fs.starfarer.api.campaign.CampaignTerrainAPI;
009import com.fs.starfarer.api.campaign.CoreUITabId;
010import com.fs.starfarer.api.campaign.PlanetAPI;
011import com.fs.starfarer.api.campaign.SectorEntityToken;
012import com.fs.starfarer.api.campaign.StarSystemAPI;
013import com.fs.starfarer.api.characters.AbilityPlugin;
014import com.fs.starfarer.api.fleet.FleetMemberAPI;
015import com.fs.starfarer.api.fleet.FleetMemberType;
016import com.fs.starfarer.api.impl.campaign.DModManager;
017import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
018import com.fs.starfarer.api.impl.campaign.ids.Abilities;
019import com.fs.starfarer.api.impl.campaign.ids.Factions;
020import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
021import com.fs.starfarer.api.impl.campaign.ids.HullMods;
022import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
023import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.TransmitterTrapSpecial;
024import com.fs.starfarer.api.ui.HintPanelAPI;
025import com.fs.starfarer.api.util.Misc;
026
027public class CampaignTutorialScript implements EveryFrameScript {
028
029        public static final String USE_TUTORIAL_RESPAWN = "$tutorialRespawn";
030        
031        public static enum CampaignTutorialStage {
032                SHOW_WELCOME_DIALOG,
033                SHOW_DEBRIS_HINT,
034                HEADING_TO_DEBRIS,
035                REACHED_DEBRIS,
036                SAVE_NAG_1,
037                SHOW_PIRATE_DIALOG,
038                SHOW_PIRATE_HINT,
039                PIRATE_APPROACHES,
040                SAVE_NAG_2,
041                SHOW_LEVELUP_DIALOG,
042                SHOW_LEVELUP_HINT,
043                WAIT_CHAR_TAB,
044                SHOW_LAY_IN_COURSE_DIALOG,
045                SHOW_LAY_IN_COURSE_HINT,
046                WAITING_TO_LAY_IN_COURSE,
047                SHOW_GO_SLOW_DIALOG,
048                SHOW_GO_SLOW_HINT,
049                WAITING_TO_GO_SLOW,
050                SHOW_SUSTAINED_BURN_DIALOG,
051                SHOW_SUSTAINED_BURN_HINT,
052                WAIT_SUSTAINED_BURN_USE,
053                SHOW_TRANSPONDER_DIALOG,
054                SHOW_TRANSPONDER_HINT,
055                WAIT_TRANSPONDER_USE,
056                DONE,
057                
058                WAITING_TO_QUICKSAVE,
059        }
060        
061        
062        protected boolean askedPlayerToSave = false;
063        protected boolean playerSaved = false;
064        protected float elapsed = 0f;
065        protected float lastCheckDistToAncyra = -1f;
066        
067        protected StarSystemAPI system;
068        protected PlanetAPI ancyra;
069        protected SectorEntityToken derinkuyu;
070        protected CampaignTutorialStage stage = CampaignTutorialStage.SHOW_WELCOME_DIALOG;
071        
072        protected boolean orbitalResetDone = false;
073        
074        protected CampaignTerrainAPI debrisField;
075        protected CampaignFleetAPI pirateFleet;
076        protected CampaignFleetAPI detachment;
077        protected TutorialMissionIntel intel;
078        
079        public CampaignTutorialScript(StarSystemAPI system) {
080                this.system = system;
081                debrisField = (CampaignTerrainAPI) system.getEntityById("debris_tutorial");
082                ancyra = (PlanetAPI) system.getEntityById("ancyra");
083                derinkuyu = system.getEntityById("derinkuyu_station");
084                
085                Global.getSector().getMemoryWithoutUpdate().set(USE_TUTORIAL_RESPAWN, true);
086        }
087
088        protected Object readResolve() {
089                return this;
090        }
091        
092        protected Object writeReplace() {
093                if (askedPlayerToSave) {
094                        playerSaved = true;
095                        HintPanelAPI hints = Global.getSector().getCampaignUI().getHintPanel();
096                        if (hints != null) {
097                                hints.clearHints(false);
098                        }
099                }
100                return this;
101        }
102        
103        protected CampaignTutorialStage quickSaveFrom = null;
104        protected boolean quickSaveNag(CampaignTutorialStage nagStage, CampaignTutorialStage next, float timeout) {
105                HintPanelAPI hints = Global.getSector().getCampaignUI().getHintPanel();
106                
107                if (stage == nagStage) {
108                        quickSaveFrom = nagStage;
109                        hints.clearHints();
110                        
111                        String control = Global.getSettings().getControlStringForEnumName("QUICK_SAVE");
112                        if (timeout > 0) {
113                                hints.setHint(0, "- Press %s to quick-save, if you like", true, Misc.getHighlightColor(), control);
114                        } else {
115                                hints.setHint(0, "- Press %s to quick-save and advance the tutorial", true, Misc.getHighlightColor(), control);
116                        }
117                        
118                        stage = CampaignTutorialStage.WAITING_TO_QUICKSAVE;
119                        elapsed = 0f;
120                        askedPlayerToSave = true;
121                        playerSaved = false;
122                        
123                        return true;
124                }
125                
126                if (quickSaveFrom == nagStage && stage == CampaignTutorialStage.WAITING_TO_QUICKSAVE && 
127                                (playerSaved || (timeout > 0 && elapsed > timeout))) {
128                        hints.clearHints();
129                        stage = next;
130                        elapsed = 0f;
131                        playerSaved = false;
132                        askedPlayerToSave = false;
133                        quickSaveFrom = null;
134                        return true;
135                }
136                
137                return false;
138        }
139        
140        protected void leashToStartLocation() {
141                CampaignFleetAPI pf = Global.getSector().getPlayerFleet();
142                float dist = Misc.getDistance(pf.getLocation(), debrisField.getLocation());
143                if (dist > 1500) {
144                        Vector2f loc = debrisField.getLocation();
145                        pf.setLocation(loc.x, loc.y);
146                        Global.getSector().getCampaignUI().showMessageDialog("Please follow the instructions near the bottom of the screen and quicksave to advance the tutorial.");
147                }
148        }
149        
150        protected boolean charTabWasOpen = false;
151        public void advance(float amount) {
152                if (Global.getSector().isInFastAdvance()) return;
153                
154                if (!orbitalResetDone) {
155                        system.getEntityById("ancyra").setCircularOrbitAngle(55f);
156                        system.getEntityById("ancyra_relay").setCircularOrbitAngle(55 - 60);;
157                        
158                        system.getEntityById("pontus").setCircularOrbitAngle(230);
159                        system.getEntityById("pontus_L4").setCircularOrbitAngle(230 + 60);
160                        system.getEntityById("pontus_L5").setCircularOrbitAngle(230 - 60);
161                        system.getEntityById("galatia_probe").setCircularOrbitAngle(230);
162                        system.getEntityById("galatia_jump_point_alpha").setCircularOrbitAngle(230 + 180f);
163                        
164                        system.getEntityById("tetra").setCircularOrbitAngle(340);
165                        system.getEntityById("derinkuyu_station").setCircularOrbitAngle(135);
166                        system.getEntityById("galatia_jump_point_fringe").setCircularOrbitAngle(160);;
167                        
168                        orbitalResetDone = true;
169                }
170                
171                
172                if (amount == 0) return;
173                
174                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
175                if (playerFleet == null) return;
176                
177                HintPanelAPI hints = Global.getSector().getCampaignUI().getHintPanel();
178                if (hints == null) return;
179                
180                //playerFleet.addAbility(Abilities.SENSOR_BURST);
181                
182                if (lastCheckDistToAncyra < 0) {
183                        lastCheckDistToAncyra = Misc.getDistance(playerFleet.getLocation(), ancyra.getLocation());
184                }
185                
186                elapsed += amount;
187                
188                if (stage == CampaignTutorialStage.SHOW_WELCOME_DIALOG && elapsed > 1f) {
189                        if (Global.getSector().getCampaignUI().showInteractionDialog(new TutorialWelcomeDialogPluginImpl(), null)) {
190                                addFleets();
191                                stage = CampaignTutorialStage.SHOW_DEBRIS_HINT;
192                        }
193                        return;
194                }
195                
196                if (stage == CampaignTutorialStage.SHOW_DEBRIS_HINT) {
197                        String control = Global.getSettings().getControlStringForAbilitySlot(5);
198                        hints.setHint(1, "- Move up into the debris field");
199                        hints.setHint(0, "- Press %s to start scavenging", false, Misc.getHighlightColor(), control);
200                        hints.makeDim(0);
201                        stage = CampaignTutorialStage.HEADING_TO_DEBRIS;
202                        return;
203                }
204                
205                if (stage == CampaignTutorialStage.HEADING_TO_DEBRIS) {
206                        if (debrisField.getPlugin().containsEntity(playerFleet)) {
207                                stage = CampaignTutorialStage.REACHED_DEBRIS;
208                                hints.fadeOutHint(1);
209                                //hints.makeNormal(0);
210                                String control = Global.getSettings().getControlStringForAbilitySlot(5);
211                                hints.setHint(0, "- Press %s to start scavenging", true, Misc.getHighlightColor(), control);
212                        }
213                        return;
214                }
215                
216                if (stage == CampaignTutorialStage.REACHED_DEBRIS) {
217                        AbilityPlugin scavenge = playerFleet.getAbility(Abilities.SCAVENGE);
218                        if (scavenge != null && scavenge.isOnCooldown()) {
219                                stage = CampaignTutorialStage.SAVE_NAG_1;
220                        }
221                        return;
222                }
223                
224                if (quickSaveFrom == CampaignTutorialStage.SAVE_NAG_1) {
225                        leashToStartLocation();
226                }
227                if (quickSaveNag(CampaignTutorialStage.SAVE_NAG_1, CampaignTutorialStage.SHOW_PIRATE_DIALOG, 0)) {
228                        return;
229                }
230
231                if (stage == CampaignTutorialStage.SHOW_PIRATE_DIALOG && elapsed >= 1f) {
232                        if (Global.getSector().getCampaignUI().showInteractionDialog(new TutorialPirateApproachesDialogPluginImpl(), null)) {
233                                stage = CampaignTutorialStage.SHOW_PIRATE_HINT;
234                        }
235                        return;
236                }
237                
238                if (stage == CampaignTutorialStage.SHOW_PIRATE_HINT) {
239                        addPirateFleet();
240                        
241                        hints.setHint(0, "- Wait for the pirates to approach, then engage and defeat them!");
242                        stage = CampaignTutorialStage.PIRATE_APPROACHES;
243                        return;
244                }
245                
246                if (stage == CampaignTutorialStage.PIRATE_APPROACHES) {
247                        if (pirateFleet == null || !pirateFleet.isAlive()) {
248                                hints.clearHints();
249                                stage = CampaignTutorialStage.SAVE_NAG_2;
250                                elapsed = 0f;
251                                
252                                long xp = Global.getSector().getPlayerPerson().getStats().getXP();
253                                long add = Global.getSettings().getLevelupPlugin().getXPForLevel(2) - xp;
254                                if (add > 0) {
255                                        Global.getSector().getPlayerPerson().getStats().addPoints(1);
256                                        Global.getSector().getPlayerPerson().getStats().addXP(add);
257                                }
258                        }
259                        return;
260                }
261                
262                if (quickSaveNag(CampaignTutorialStage.SAVE_NAG_2, CampaignTutorialStage.SHOW_LEVELUP_DIALOG, 0)) {
263                        return;
264                }
265                
266                if (stage == CampaignTutorialStage.SHOW_LEVELUP_DIALOG && elapsed >= 1f) {
267                        if (Global.getSector().getCampaignUI().showInteractionDialog(new TutorialLevelUpDialogPluginImpl(), null)) {
268                                stage = CampaignTutorialStage.SHOW_LEVELUP_HINT;
269                        }
270                        return;
271                }
272                
273                if (stage == CampaignTutorialStage.SHOW_LEVELUP_HINT) {
274                        String character = Global.getSettings().getControlStringForEnumName("CORE_CHARACTER");
275                        hints.setHint(0, "- Press %s to open the character tab and consider your options", true, Misc.getHighlightColor(), character);
276                        stage = CampaignTutorialStage.WAIT_CHAR_TAB;
277                        return;
278                }
279                
280                if (stage == CampaignTutorialStage.WAIT_CHAR_TAB) {
281                        CoreUITabId tab = Global.getSector().getCampaignUI().getCurrentCoreTab();
282                        if (tab == CoreUITabId.CHARACTER) {
283                                charTabWasOpen = true;
284                        }
285                        if (charTabWasOpen && !Global.getSector().getCampaignUI().isShowingDialog()) {
286                                stage = CampaignTutorialStage.SHOW_LAY_IN_COURSE_DIALOG;
287                                elapsed = 0f;
288                                hints.clearHints();
289                        }
290                }
291
292                if (stage == CampaignTutorialStage.SHOW_LAY_IN_COURSE_DIALOG && elapsed >= 1f) {
293                        startTutorialMissionEvent();
294                        if (Global.getSector().getCampaignUI().showInteractionDialog(
295                                        new TutorialLayInCourseDialogPluginImpl(ancyra.getMarket(), intel.getMainContact()), null)) {
296                                stage = CampaignTutorialStage.SHOW_LAY_IN_COURSE_HINT;
297                        }
298                        return;
299                }
300                
301                
302                if (stage == CampaignTutorialStage.SHOW_LAY_IN_COURSE_HINT) {
303                        String intel = Global.getSettings().getControlStringForEnumName("CORE_INTEL");
304                        String map = Global.getSettings().getControlStringForEnumName("CORE_MAP");
305                        String openMap = Global.getSettings().getControlStringForEnumName("SUBTAB_4");
306                        
307                        hints.setHint(2, "- Press %s to open the intel tab, and select the mission", false, Misc.getHighlightColor(), intel);
308                        hints.setHint(1, "- Press %s to open the map on the mission target", false, Misc.getHighlightColor(), openMap);
309                        hints.setHint(0, "- Click on " + ancyra.getName() + " and select " +
310                                        "%s, then press %s to close the map", false, Misc.getHighlightColor(), "\"Lay in Course\"", map);
311                        stage = CampaignTutorialStage.WAITING_TO_LAY_IN_COURSE;
312                        
313//                      hints.setHint(1, "- Press %s to open the map", Misc.getHighlightColor(), map);
314//                      hints.setHint(0, "- Find " + ancyra.getName() + ", left-click on it and select " +
315//                                      "\"Lay in Course\", then close the map", Misc.getHighlightColor(), "\"Lay in Course\"");
316//                      stage = CampaignTutorialStage.WAITING_TO_LAY_IN_COURSE;
317                        return;
318                }
319                
320                if (stage == CampaignTutorialStage.WAITING_TO_LAY_IN_COURSE) {
321                        float dist = Misc.getDistance(playerFleet.getLocation(), ancyra.getLocation());
322                        boolean closedIn = dist < lastCheckDistToAncyra * 0.75f;
323                        if (closedIn || (playerFleet.getInteractionTarget() != null &&
324                                        playerFleet.getInteractionTarget().getMarket() == ancyra.getMarket())) {
325                                lastCheckDistToAncyra = dist;
326                                hints.clearHints();
327                                stage = CampaignTutorialStage.SHOW_SUSTAINED_BURN_DIALOG;
328                                elapsed = 0;
329                        }
330                        return;
331                }
332
333                
334                if (stage == CampaignTutorialStage.SHOW_SUSTAINED_BURN_DIALOG && elapsed > 5f) {
335                        if (Global.getSector().getCampaignUI().showInteractionDialog(new TutorialSustainedBurnDialogPluginImpl(ancyra.getMarket()), null)) {
336                                stage = CampaignTutorialStage.SHOW_SUSTAINED_BURN_HINT;
337                        }
338                        return;
339                }
340                
341                if (stage == CampaignTutorialStage.SHOW_SUSTAINED_BURN_HINT) {
342                        String control = Global.getSettings().getControlStringForAbilitySlot(4);
343                        hints.setHint(0, "- Press %s to engage sustained burn", true, Misc.getHighlightColor(), control);
344                        stage = CampaignTutorialStage.WAIT_SUSTAINED_BURN_USE;
345                        elapsed = 0;
346                        return;
347                }
348                
349                if (stage == CampaignTutorialStage.WAIT_SUSTAINED_BURN_USE) {
350                        AbilityPlugin sb = playerFleet.getAbility(Abilities.SUSTAINED_BURN);
351                        float dist = Misc.getDistance(playerFleet.getLocation(), ancyra.getLocation());
352                        boolean closedIn = dist < lastCheckDistToAncyra * 0.75f;
353                        if ((sb != null && sb.isActive() && elapsed > 5f) || closedIn) {
354                                lastCheckDistToAncyra = dist;
355                                hints.clearHints();
356                                stage = CampaignTutorialStage.SHOW_GO_SLOW_DIALOG;
357                                elapsed = 0f;
358                        }
359                        return;
360                }
361                
362                
363                if (stage == CampaignTutorialStage.SHOW_GO_SLOW_DIALOG && 
364                                Global.getSector().getPlayerFleet().getLocation().length() < 9300) {
365                        if (Global.getSector().getCampaignUI().showInteractionDialog(new TutorialGoSlowDialogPluginImpl(), null)) {
366                                stage = CampaignTutorialStage.SHOW_GO_SLOW_HINT;
367                        }
368                        return;
369                }
370                
371                if (stage == CampaignTutorialStage.SHOW_GO_SLOW_HINT) {
372                        String control = Global.getSettings().getControlStringForEnumName("GO_SLOW");
373                        hints.clearHints();
374                        hints.setHint(0, "- Press and hold %s to move slowly through the asteroid belt", true, Misc.getHighlightColor(), control);
375                        stage = CampaignTutorialStage.WAITING_TO_GO_SLOW;
376                        elapsed = 0;
377                        return;
378                }
379                
380                
381                if (stage == CampaignTutorialStage.WAITING_TO_GO_SLOW && 
382                                Global.getSector().getPlayerFleet().getLocation().length() < 7850) {
383                        float dist = Misc.getDistance(playerFleet.getLocation(), ancyra.getLocation());
384                        boolean closedIn = dist < lastCheckDistToAncyra * 0.75f;
385                        if (closedIn || (playerFleet.getInteractionTarget() != null &&
386                                        playerFleet.getInteractionTarget().getMarket() == ancyra.getMarket())) {
387                                lastCheckDistToAncyra = dist;
388                                hints.clearHints();
389                                stage = CampaignTutorialStage.SHOW_TRANSPONDER_DIALOG;
390                                elapsed = 0;
391                        }
392                        return;
393                }
394                
395                
396                if (stage == CampaignTutorialStage.SHOW_TRANSPONDER_DIALOG) {
397                        float dist = Misc.getDistance(playerFleet.getLocation(), ancyra.getLocation());
398                        if (dist < 6000) {
399                                if (Global.getSector().getCampaignUI().showInteractionDialog(new TutorialTransponderDialogPluginImpl(ancyra.getMarket()), null)) {
400                                        stage = CampaignTutorialStage.SHOW_TRANSPONDER_HINT;
401                                }
402                        }
403                        return;
404                }
405                
406                if (stage == CampaignTutorialStage.SHOW_TRANSPONDER_HINT) {
407                        String control = Global.getSettings().getControlStringForAbilitySlot(0);
408                        hints.setHint(0, "- Press %s twice to turn on the transponder", true, Misc.getHighlightColor(), control);
409                        stage = CampaignTutorialStage.WAIT_TRANSPONDER_USE;
410                        elapsed = 0;
411                        return;
412                }
413                
414                if (stage == CampaignTutorialStage.WAIT_TRANSPONDER_USE) {
415                        AbilityPlugin transponder = playerFleet.getAbility(Abilities.TRANSPONDER);
416                        if ((transponder != null && transponder.isActive())) {
417                                hints.clearHints();
418                                stage = CampaignTutorialStage.DONE;
419                                elapsed = 0f;
420                        }
421                        return;
422                }
423        }
424        
425        
426        protected void addFleets() {
427                addSecurityDetachment();
428                
429                SectorEntityToken inner = system.getEntityById("galatia_jump_point_alpha");
430                SectorEntityToken fringe = system.getEntityById("galatia_jump_point_fringe");
431                SectorEntityToken derinkuyu = system.getEntityById("derinkuyu_station");
432                
433                CampaignFleetAPI g1 = RogueMinerMiscFleetManager.createGuardFleet(false);
434                g1.addScript(new TutorialLeashAssignmentAI(g1, system, derinkuyu));
435                system.addEntity(g1);
436                g1.setLocation(derinkuyu.getLocation().x, derinkuyu.getLocation().y);
437                
438                CampaignFleetAPI g2 = RogueMinerMiscFleetManager.createGuardFleet(Misc.isEasy());
439                
440                if (!Misc.isEasy()) {
441                        FleetMemberAPI member = Global.getFactory().createFleetMember(FleetMemberType.SHIP, "venture_Outdated");
442                        member.setVariant(member.getVariant().clone(), false, false);
443                        DModManager.setDHull(member.getVariant());
444                        member.getVariant().addPermaMod(HullMods.COMP_ARMOR, false);
445                        member.getVariant().addPermaMod(HullMods.FAULTY_GRID, false);
446                        g2.getFleetData().addFleetMember(member);
447                }
448                
449                g2.getFleetData().sort();
450                g2.addScript(new TutorialLeashAssignmentAI(g2, system, inner));
451                system.addEntity(g2);
452                g2.setLocation(inner.getLocation().x, inner.getLocation().y);
453                
454                CampaignFleetAPI g3 = RogueMinerMiscFleetManager.createGuardFleet(true);
455                g3.addScript(new TutorialLeashAssignmentAI(g3, system, inner));
456                system.addEntity(g3);
457                g3.setLocation(inner.getLocation().x, inner.getLocation().y);
458                
459                
460                CampaignFleetAPI g4 = RogueMinerMiscFleetManager.createGuardFleet(true);
461                g4.addScript(new TutorialLeashAssignmentAI(g4, system, fringe));
462                system.addEntity(g4);
463                g4.setLocation(fringe.getLocation().x, fringe.getLocation().y);
464                
465                CampaignFleetAPI g5 = RogueMinerMiscFleetManager.createGuardFleet(true);
466                g5.addScript(new TutorialLeashAssignmentAI(g5, system, fringe));
467                system.addEntity(g5);
468                g5.setLocation(fringe.getLocation().x, fringe.getLocation().y);
469                
470        }
471        
472        
473        protected void startTutorialMissionEvent() {
474                if (intel == null) intel = new TutorialMissionIntel();
475        }
476        
477        protected void addPirateFleet() {
478                pirateFleet = RogueMinerMiscFleetManager.createEmptyRogueFleet("Rogue Miner", false);
479                pirateFleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_NO_SHIP_RECOVERY, true);
480                
481                FleetMemberAPI member = Global.getFactory().createFleetMember(FleetMemberType.SHIP, "cerberus_d_pirates_Standard");
482                pirateFleet.getFleetData().addFleetMember(member);
483        
484                system.addEntity(pirateFleet);
485                CampaignFleetAPI playerFleet = Global.getSector().getPlayerFleet();
486                pirateFleet.setLocation(playerFleet.getLocation().x + 750f, playerFleet.getLocation().y + 750f);
487                
488                TransmitterTrapSpecial.makeFleetInterceptPlayer(pirateFleet, true, true, 100f);
489        }
490        
491        protected void addSecurityDetachment() {
492                detachment = FleetFactoryV3.createEmptyFleet(Factions.HEGEMONY, FleetTypes.PATROL_MEDIUM, ancyra.getMarket());
493                detachment.setName("Security Detachment");
494                detachment.setNoFactionInName(true);
495                
496                //detachment.getFleetData().addFleetMember("eagle_xiv_Elite");
497                detachment.getFleetData().addFleetMember("dominator_XIV_Elite");
498                detachment.getFleetData().addFleetMember("mora_Strike");
499                detachment.getFleetData().addFleetMember("enforcer_Escort");
500                detachment.getFleetData().addFleetMember("enforcer_Assault");
501                detachment.getFleetData().addFleetMember("lasher_CS");
502                detachment.getFleetData().addFleetMember("lasher_CS");
503                
504                detachment.clearAbilities();
505                detachment.addAbility(Abilities.TRANSPONDER);
506                detachment.addAbility(Abilities.GO_DARK);
507                detachment.addAbility(Abilities.SENSOR_BURST);
508                detachment.addAbility(Abilities.EMERGENCY_BURN);
509                
510                detachment.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PATROL_FLEET, true);
511                detachment.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_NO_JUMP, true);
512                
513                system.addEntity(detachment);
514                detachment.setLocation(ancyra.getLocation().x, ancyra.getLocation().y);
515                
516                detachment.addScript(new TutorialLeashAssignmentAI(detachment, system, ancyra));
517                
518                detachment.setId("tutorial_security_detachment");
519        }
520        
521        
522
523        public boolean isDone() {
524                return stage == CampaignTutorialStage.DONE;
525        }
526
527        public boolean runWhilePaused() {
528                return stage == CampaignTutorialStage.WAIT_CHAR_TAB;
529        }
530
531}