4 using System.Collections.Generic;
18 private const float FadeOutTime = 3f;
19 private const float WaitBeforeFade = 4f;
23 #region Tutorial variables
30 private bool completed;
39 if (completed == value) {
return; }
45 GameSettings.SaveCurrentConfig();
66 public bool Paused {
get;
private set; }
70 #region Tutorial Controls
74 Identifier = $
"tutorial.{prefab.Identifier}".ToIdentifier();
76 Description = TextManager.Get($
"tutorial.{prefab.Identifier}.description");
81 private IEnumerable<CoroutineStatus> Loading()
92 if (generationParams is not
null)
95 Biome.
Prefabs.FirstOrDefault(b => generationParams.AllowedBiomeIdentifiers.Contains(b.Identifier)) ??
98 if (!
string.IsNullOrEmpty(StartOutpostPath))
108 GameMain.GameSession.StartRound(LevelSeed);
111 GameMain.GameSession.EventManager.ClearEvents();
112 GameMain.GameSession.EventManager.Enabled =
true;
113 GameMain.GameScreen.Select();
119 foreach (Structure wall
in Structure.WallList)
121 if (wall.Submarine !=
null && wall.Submarine.Info.IsOutpost)
123 wall.Indestructible =
true;
129 var wayPoint = WayPoint.GetRandom(SpawnPointType, charInfo.Job?.Prefab, Level.Loaded.StartOutpost);
131 if (wayPoint ==
null)
133 DebugConsole.ThrowError(
"A waypoint with the spawntype \"" + SpawnPointType +
"\" is required for the tutorial event");
134 yield
return CoroutineStatus.Failure;
138 character =
Character.Create(charInfo, wayPoint.WorldPosition,
"", isRemotePlayer:
false, hasAi:
false);
146 DebugConsole.ThrowError(
"Item prefab \"ID Card\" not found!");
147 yield
return CoroutineStatus.Failure;
151 idCard.AddTag(
"eng");
153 foreach (Item item
in Item.ItemList)
155 Door door = item.GetComponent<
Door>();
162 tutorialCoroutine = CoroutineManager.StartCoroutine(
UpdateState());
165 GameMain.GameSession.CrewManager.AutoHideCrewList();
167 if (
Character.Controlled?.Inventory is CharacterInventory inventory)
169 foreach (Item item
in inventory.AllItemsMod)
173 Character.Controlled.Inventory.RemoveItem(item);
177 yield
return CoroutineStatus.Success;
185 ObjectiveManager.ResetObjectives();
190 var door = item.GetComponent<
Door>();
193 if (door.RequiredItems.Values.None(ris => ris.None(ri => ri.Identifiers.None(i => i ==
"locked"))))
203 if (character !=
null)
211 CoroutineManager.StartCoroutine(Dead());
215 if (tutorialCoroutine !=
null)
217 CoroutineManager.StopCoroutines(tutorialCoroutine);
219 if (completedCoroutine ==
null && !CoroutineManager.IsCoroutineRunning(completedCoroutine))
221 GUI.PreventPauseMenuToggle =
false;
223 ObjectiveManager.ClearContent();
232 private IEnumerable<CoroutineStatus> Dead()
234 GUI.PreventPauseMenuToggle =
true;
238 GameAnalyticsManager.AddDesignEvent(
"Tutorial:Died");
242 var messageBox =
new GUIMessageBox(TextManager.Get(
"Tutorial.TryAgainHeader"), TextManager.Get(
"Tutorial.TryAgain"),
new LocalizedString[] { TextManager.Get(
"Yes"), TextManager.Get(
"No") });
244 messageBox.Buttons[0].OnClicked += Restart;
245 messageBox.Buttons[0].OnClicked += messageBox.Close;
249 messageBox.Buttons[1].OnClicked += messageBox.Close;
261 if (eventPrefab ==
null)
263 DebugConsole.LogError($
"No tutorial event defined for the tutorial (identifier: \"{TutorialPrefab?.Identifier.ToString() ?? "null"})\"");
270 while (!eventInstance.IsFinished)
277 DebugConsole.LogError($
"Failed to create an instance for a tutorial event (identifier: \"{eventPrefab.Identifier}\"");
286 GameAnalyticsManager.AddDesignEvent($
"Tutorial:{Identifier}:Completed");
287 completedCoroutine = CoroutineManager.StartCoroutine(TutorialCompleted());
289 IEnumerable<CoroutineStatus> TutorialCompleted()
293 GUI.PreventPauseMenuToggle =
true;
296 GameAnalyticsManager.AddDesignEvent(
"Tutorial:Completed");
303 bool displayEndMessage =
307 if (displayEndMessage)
312 text: TextManager.Get($
"{Identifier}.completed"),
315 TextManager.Get(nextTutorialPrefab is null ?
"restart" :
"campaigncontinue"),
316 TextManager.Get(
"pausemenuquit")
319 endingMessageBox.Buttons[0].OnClicked += (_, _) =>
321 if (nextTutorialPrefab is
null)
323 onEnd = () => Restart(
null,
null);
330 new Tutorial(nextTutorialPrefab).Start();
335 endingMessageBox.Buttons[0].OnClicked += endingMessageBox.Close;
336 endingMessageBox.Buttons[0].OnClicked += (_, _) =>
Paused =
false;
337 endingMessageBox.Buttons[1].OnClicked += endingMessageBox.Close;
338 endingMessageBox.Buttons[1].OnClicked += (_, _) =>
Paused =
false;
353 private bool Restart(
GUIButton button,
object obj)
363 if (tutorialCoroutine !=
null)
365 CoroutineManager.StopCoroutines(tutorialCoroutine);
367 ObjectiveManager.ResetUI();
static readonly PrefabCollection< Biome > Prefabs
CharacterInventory Inventory
static Character? Controlled
void GiveJobItems(bool isPvPMode, WayPoint spawnPoint=null)
static CompletedTutorials Instance
void Add(Identifier identifier)
static CoroutineStatus Running
static CoroutineStatus Failure
static CoroutineStatus Success
readonly Queue< Event > QueuedEvents
Event sets are sets of random events that occur within a level (most commonly, monster spawns and scr...
static EventPrefab GetEventPrefab(Identifier identifier)
static readonly List< GUIComponent > MessageBoxes
static GameSession?? GameSession
CoroutineHandle ShowLoading(IEnumerable< CoroutineStatus > loader, bool waitKeyHit=true)
static GameScreen GameScreen
static MainMenuScreen MainMenuScreen
static GameModePreset Tutorial
readonly EventManager EventManager
void StartRound(string levelSeed, float? difficulty=null, LevelGenerationParams? levelGenerationParams=null, Identifier forceBiome=default)
Item FindItemByTag(Identifier tag, bool recursive=false)
static readonly List< Item > ItemList
Dictionary< RelatedItem.RelationType, List< RelatedItem > > RequiredItems
static readonly PrefabCollection< LevelGenerationParams > LevelParams
bool ReturnToMainMenu(GUIButton button, object obj)
static Submarine MainSub
Note that this can be null in some situations, e.g. editors and missions that don't load a submarine.
static readonly PrefabCollection< TutorialPrefab > Prefabs
readonly bool AllowCharacterSwitch
readonly ImmutableArray< Identifier > StartingItemTags
readonly ContentPath SubmarinePath
readonly Identifier EventIdentifier
readonly ContentPath OutpostPath
readonly EndMessageInfo EndMessage
readonly string LevelSeed
CharacterInfo GetTutorialCharacterInfo()
readonly string LevelParams
readonly List<(Entity entity, Identifier iconStyle)> Icons
Tutorial(TutorialPrefab prefab)
IEnumerable< CoroutineStatus > UpdateState()
readonly Identifier Identifier
LocalizedString DisplayName
readonly TutorialPrefab TutorialPrefab
LocalizedString Description
@ Character
Characters only
@ Structure
Structures and hulls, but also items (for backwards support)!