2 using System.Collections.Generic;
3 using System.Collections.Immutable;
5 using System.Reflection;
35 public static readonly Dictionary<MissionType, Type>
CoOpMissionClasses =
new Dictionary<MissionType, Type>()
51 public static readonly Dictionary<MissionType, Type>
PvPMissionClasses =
new Dictionary<MissionType, Type>()
65 Amount = element.GetAttributeFloat(nameof(
Amount), 0.0f);
72 private readonly ConstructorInfo constructor;
80 public readonly ImmutableHashSet<Identifier>
Tags;
114 public readonly ImmutableArray<LocalizedString>
Headers;
115 public readonly ImmutableArray<LocalizedString>
Messages;
163 public int State {
get;
private set; }
166 public float Delay {
get;
private set; }
177 public readonly List<TriggerEvent>
TriggerEvents =
new List<TriggerEvent>();
196 if (
string.IsNullOrEmpty(textTag))
198 return TextManager.Get($
"{textTagPrefix}.{TextIdentifier}");
204 TextManager.Get(textTag)
206 .
Fallback(TextManager.Get($
"{textTagPrefix}.{TextIdentifier}"))
219 RequireThalamusWreck = element.
GetAttributeBool(
"requirethalamuswreck",
false);
244 SuccessMessage = TextManager.Get($
"MissionSuccess.{TextIdentifier}");
245 if (!
string.IsNullOrEmpty(successMessageTag))
248 .
Fallback(TextManager.Get(successMessageTag))
254 FailureMessage = TextManager.Get($
"MissionFailure.{TextIdentifier}");
255 if (!
string.IsNullOrEmpty(failureMessageTag))
258 .
Fallback(TextManager.Get(failureMessageTag))
265 TextManager.Get($
"MissionSonarLabel.{sonarLabelTag}")
266 .
Fallback(TextManager.Get(sonarLabelTag))
267 .
Fallback(TextManager.Get($
"MissionSonarLabel.{TextIdentifier}"));
268 if (!
string.IsNullOrEmpty(sonarLabelTag))
282 var headers =
new List<LocalizedString>();
283 var messages =
new List<LocalizedString>();
286 for (
int i = 0; i < 100; i++)
288 LocalizedString header = TextManager.Get($
"MissionHeader{i}.{TextIdentifier}");
289 LocalizedString message = TextManager.Get($
"MissionMessage{i}.{TextIdentifier}");
290 if (!message.IsNullOrEmpty())
293 messages.Add(message);
297 List<ReputationReward> reputationRewards =
new List<ReputationReward>();
298 int messageIndex = 0;
299 foreach (var subElement
in element.Elements())
301 switch (subElement.Name.ToString().ToLowerInvariant())
304 if (messageIndex > headers.Count - 1)
306 headers.Add(
string.Empty);
307 messages.Add(
string.Empty);
309 headers[messageIndex] =
310 TextManager.Get($
"MissionHeader{messageIndex}.{TextIdentifier}")
311 .Fallback(TextManager.Get(subElement.GetAttributeString(
"header",
"")))
312 .Fallback(subElement.GetAttributeString(
"header",
""));
313 messages[messageIndex] =
314 TextManager.Get($
"MissionMessage{messageIndex}.{TextIdentifier}")
315 .Fallback(TextManager.Get(subElement.GetAttributeString(
"text",
"")))
316 .Fallback(subElement.GetAttributeString(
"text",
""));
320 case "connectiontype":
321 if (subElement.GetAttribute(
"identifier") !=
null)
328 subElement.GetAttributeIdentifier(
"from",
""),
329 subElement.GetAttributeIdentifier(
"to",
"")));
332 case "locationtypechange":
336 case "reputationreward":
341 string stringValue = subElement.GetAttributeString(
"value",
string.Empty);
342 if (!
string.IsNullOrWhiteSpace(stringValue) && !identifier.IsEmpty)
347 string operatingString = subElement.GetAttributeString(
"operation",
string.Empty);
348 if (!
string.IsNullOrWhiteSpace(operatingString))
361 Headers = headers.ToImmutableArray();
362 Messages = messages.ToImmutableArray();
368 if (missionTypeName ==
"outpostdestroy" || missionTypeName ==
"outpostrescue")
370 missionTypeName = nameof(
MissionType.AbandonedOutpost).ToIdentifier();
372 else if (missionTypeName ==
"clearalienruins")
374 missionTypeName = nameof(
MissionType.EliminateTargets).ToIdentifier();
377 if (!Enum.TryParse(missionTypeName.Value,
true, out
Type))
379 DebugConsole.ThrowErrorLocalized(
"Error in mission prefab \"" +
Name +
"\" - \"" + missionTypeName +
"\" is not a valid mission type.");
384 DebugConsole.ThrowErrorLocalized(
"Error in mission prefab \"" +
Name +
"\" - mission type cannot be none.");
390 DebugConsole.AddWarning($
"Potential error in mission prefab \"{Identifier}\" - sonar label not set.");
404 DebugConsole.ThrowErrorLocalized(
"Error in mission prefab \"" +
Name +
"\" - unsupported mission type \"" +
Type.ToString() +
"\"");
406 if (constructor ==
null)
408 DebugConsole.ThrowError($
"Failed to find a constructor for the mission type \"{Type}\"!",
409 contentPackage: element.ContentPackage);
412 InitProjSpecific(element);
433 if (fromType ==
"any" ||
437 if (toType ==
"any" ||
456 return constructor?.Invoke(
new object[] {
this, locations, sub }) as
Mission;
459 partial
void DisposeProjectSpecific();
462 DisposeProjectSpecific();
string? GetAttributeString(string key, string? def)
Identifier[] GetAttributeIdentifierArray(Identifier[] def, params string[] keys)
bool GetAttributeBool(string key, bool def)
int GetAttributeInt(string key, int def)
string?[] GetAttributeStringArray(string key, string[]? def, bool convertToLowerInvariant=false)
XAttribute? GetAttribute(string name)
Identifier GetAttributeIdentifier(string key, string def)
Makes the event jump to a Label somewhere else in the event.
LocalizedString Fallback(LocalizedString fallback, bool useDefaultLanguageIfFound=true)
Use this text instead if the original text cannot be found.
readonly Identifier FactionIdentifier
readonly float AmountForOpposingFaction
ReputationReward(XElement element)
TriggerEvent(XElement element)
readonly Identifier AchievementIdentifier
readonly LocalizedString SonarLabel
readonly ImmutableList< ReputationReward > ReputationRewards
bool IsAllowed(Location from, Location to)
readonly? int Difficulty
Displayed difficulty (indicator)
readonly int MaxLevelDifficulty
The actual maximum difficulty of the level allowed for this mission to trigger.
static readonly Dictionary< MissionType, Type > CoOpMissionClasses
static readonly PrefabCollection< MissionPrefab > Prefabs
readonly Identifier SonarIconIdentifier
readonly bool AllowOtherMissionsInLevel
readonly MissionType Type
readonly bool ShowInMenus
readonly List< TriggerEvent > TriggerEvents
readonly int MaxProgressState
readonly List<(Identifier from, Identifier to)> AllowedConnectionTypes
The mission can only be received when travelling from a location of the first type to a location of t...
readonly bool BlockLocationTypeChanges
If enabled, locations this mission takes place in cannot change their type
readonly int MinLevelDifficulty
The actual minimum difficulty of the level allowed for this mission to trigger.
readonly LocalizedString ProgressBarLabel
readonly ImmutableArray< LocalizedString > Headers
LocationTypeChange LocationTypeChangeOnCompleted
readonly List<(Identifier Identifier, object Value, SetDataAction.OperationType OperationType)> DataRewards
readonly ImmutableHashSet< Identifier > Tags
readonly Identifier RequiredLocationFaction
The mission can only happen in locations owned by this faction. In the mission mode,...
readonly bool RequireWreck
readonly LocalizedString Name
readonly LocalizedString Description
readonly ImmutableArray< LocalizedString > Messages
readonly bool MultiplayerOnly
readonly bool IsSideObjective
readonly List< Identifier > AllowedLocationTypes
The mission can only be received in these location types
static readonly HashSet< MissionType > HiddenMissionClasses
readonly LocalizedString FailureMessage
MissionPrefab(ContentXElement element, MissionsFile file)
readonly LocalizedString SuccessMessage
bool IsAllowedDifficulty(float difficulty)
Inclusive (matching the min an max values is accepted).
readonly List< string > UnhideEntitySubCategories
Show entities belonging to these sub categories when the mission starts
readonly bool ShowProgressBar
readonly Identifier TextIdentifier
readonly bool ShowProgressInNumbers
static readonly Dictionary< MissionType, Type > PvPMissionClasses
readonly ContentXElement ConfigElement
Mission Instantiate(Location[] locations, Submarine sub)
readonly Identifier Identifier
Prefab that has a property serves as a deterministic hash of a prefab's identifier....
static Dictionary< Identifier, SerializableProperty > DeserializeProperties(object obj, XElement element=null)
Sets a campaign metadata value. The metadata can be any arbitrary data you want to save: for example,...
static object ConvertXMLValue(string value)