public MissionPrefab(XElement element) { ConfigElement = element; Identifier = element.GetAttributeString("identifier", ""); TextIdentifier = element.GetAttributeString("textidentifier", null) ?? Identifier; Name = TextManager.Get("MissionName." + TextIdentifier, true) ?? element.GetAttributeString("name", ""); Description = TextManager.Get("MissionDescription." + TextIdentifier, true) ?? element.GetAttributeString("description", ""); Reward = element.GetAttributeInt("reward", 1); Commonness = element.GetAttributeInt("commonness", 1); SuccessMessage = TextManager.Get("MissionSuccess." + TextIdentifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully"); FailureMessage = TextManager.Get("MissionFailure." + TextIdentifier, true) ?? ""; if (string.IsNullOrEmpty(FailureMessage) && TextManager.ContainsTag("missionfailed")) { FailureMessage = TextManager.Get("missionfailed", returnNull: true) ?? ""; } if (string.IsNullOrEmpty(FailureMessage) && GameMain.Config.Language == "English") { FailureMessage = element.GetAttributeString("failuremessage", ""); } SonarLabel = TextManager.Get("MissionSonarLabel." + TextIdentifier, true) ?? element.GetAttributeString("sonarlabel", ""); SonarIconIdentifier = element.GetAttributeString("sonaricon", ""); MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false); SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false); AchievementIdentifier = element.GetAttributeString("achievementidentifier", ""); Headers = new List <string>(); Messages = new List <string>(); AllowedLocationTypes = new List <Pair <string, string> >(); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "message": int index = Messages.Count; Headers.Add(TextManager.Get("MissionHeader" + index + "." + TextIdentifier, true) ?? subElement.GetAttributeString("header", "")); Messages.Add(TextManager.Get("MissionMessage" + index + "." + TextIdentifier, true) ?? subElement.GetAttributeString("text", "")); break; case "locationtype": AllowedLocationTypes.Add(new Pair <string, string>( subElement.GetAttributeString("from", ""), subElement.GetAttributeString("to", ""))); break; } } string missionTypeName = element.GetAttributeString("type", ""); if (!Enum.TryParse(missionTypeName, out Type)) { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - \"" + missionTypeName + "\" is not a valid mission type."); return; } if (Type == MissionType.None) { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - mission type cannot be none."); return; } constructor = missionClasses[Type].GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) }); InitProjSpecific(element); }
public string GetHullNameTextId() { var textId = $"roomname.{Identifier}"; return(TextManager.ContainsTag(textId) ? textId : null); }
public void CreateSettingsFrame(GUIComponent parent) { if (TextManager.ContainsTag("Karma.ResetKarmaBetweenRounds")) { CreateLabeledTickBox(parent, "ResetKarmaBetweenRounds"); } CreateLabeledSlider(parent, 0.0f, 40.0f, 1.0f, nameof(KickBanThreshold)); if (TextManager.ContainsTag("Karma.KicksBeforeBan")) { CreateLabeledNumberInput(parent, 0, 10, nameof(KicksBeforeBan)); } CreateLabeledSlider(parent, 0.0f, 50.0f, 1.0f, nameof(HerpesThreshold)); CreateLabeledSlider(parent, 0.0f, 0.5f, 0.01f, nameof(KarmaDecay)); CreateLabeledSlider(parent, 50.0f, 100.0f, 1.0f, nameof(KarmaDecayThreshold)); CreateLabeledSlider(parent, 0.0f, 0.5f, 0.01f, nameof(KarmaIncrease)); CreateLabeledSlider(parent, 0.0f, 50.0f, 1.0f, nameof(KarmaIncreaseThreshold)); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.12f), parent.RectTransform), TextManager.Get("Karma.PositiveActions"), textAlignment: Alignment.Center, font: GUI.SubHeadingFont) { CanBeFocused = false }; CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(StructureRepairKarmaIncrease)); CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(HealFriendlyKarmaIncrease)); CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(DamageEnemyKarmaIncrease)); CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(ItemRepairKarmaIncrease)); CreateLabeledSlider(parent, 0.0f, 10.0f, 0.05f, nameof(ExtinguishFireKarmaIncrease)); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.12f), parent.RectTransform), TextManager.Get("Karma.NegativeActions"), textAlignment: Alignment.Center, font: GUI.SubHeadingFont) { CanBeFocused = false }; CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(StructureDamageKarmaDecrease)); CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(DamageFriendlyKarmaDecrease)); //hide these for now if a localized text is not available if (TextManager.ContainsTag("Karma." + nameof(StunFriendlyKarmaDecrease))) { CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(StunFriendlyKarmaDecrease)); } if (TextManager.ContainsTag("Karma." + nameof(StunFriendlyKarmaDecreaseThreshold))) { CreateLabeledSlider(parent, 0.0f, 10.0f, 1.0f, nameof(StunFriendlyKarmaDecreaseThreshold)); } CreateLabeledSlider(parent, 0.0f, 100.0f, 1.0f, nameof(ReactorMeltdownKarmaDecrease)); CreateLabeledSlider(parent, 0.0f, 10.0f, 0.05f, nameof(ReactorOverheatKarmaDecrease)); CreateLabeledNumberInput(parent, 0, 20, nameof(AllowedWireDisconnectionsPerMinute)); CreateLabeledSlider(parent, 0.0f, 20.0f, 0.5f, nameof(WireDisconnectionKarmaDecrease)); CreateLabeledSlider(parent, 0.0f, 30.0f, 1.0f, nameof(SpamFilterKarmaDecrease)); //hide these for now if a localized text is not available if (TextManager.ContainsTag("Karma." + nameof(DangerousItemStealKarmaDecrease))) { CreateLabeledSlider(parent, 0.0f, 30.0f, 1.0f, nameof(DangerousItemStealKarmaDecrease)); } if (TextManager.ContainsTag("Karma." + nameof(DangerousItemStealBots))) { CreateLabeledTickBox(parent, nameof(DangerousItemStealBots)); } }
public void Draw(SpriteBatch spriteBatch, GUICustomComponent mapContainer) { Rectangle rect = mapContainer.Rect; Vector2 viewSize = new Vector2(rect.Width / zoom, rect.Height / zoom); float edgeBuffer = size * (BackgroundScale - 1.0f) / 2; drawOffset.X = MathHelper.Clamp(drawOffset.X, -size - edgeBuffer + viewSize.X / 2.0f, edgeBuffer - viewSize.X / 2.0f); drawOffset.Y = MathHelper.Clamp(drawOffset.Y, -size - edgeBuffer + viewSize.Y / 2.0f, edgeBuffer - viewSize.Y / 2.0f); drawOffsetNoise = new Vector2( (float)PerlinNoise.CalculatePerlin(Timing.TotalTime * 0.1f % 255, Timing.TotalTime * 0.1f % 255, 0) - 0.5f, (float)PerlinNoise.CalculatePerlin(Timing.TotalTime * 0.2f % 255, Timing.TotalTime * 0.2f % 255, 0.5f) - 0.5f) * 10.0f; Vector2 viewOffset = drawOffset + drawOffsetNoise; Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y) + CenterOffset; Rectangle prevScissorRect = GameMain.Instance.GraphicsDevice.ScissorRectangle; spriteBatch.End(); spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, rect); spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable); for (int x = 0; x < mapTiles.GetLength(0); x++) { for (int y = 0; y < mapTiles.GetLength(1); y++) { Vector2 mapPos = new Vector2( x * generationParams.TileSpriteSpacing.X + ((y % 2 == 0) ? 0.0f : generationParams.TileSpriteSpacing.X * 0.5f), y * generationParams.TileSpriteSpacing.Y); mapPos.X -= size / 2 * (BackgroundScale - 1.0f); mapPos.Y -= size / 2 * (BackgroundScale - 1.0f); Vector2 scale = new Vector2( generationParams.TileSpriteSize.X / mapTiles[x, y].Sprite.size.X, generationParams.TileSpriteSize.Y / mapTiles[x, y].Sprite.size.Y); mapTiles[x, y].Sprite.Draw(spriteBatch, rectCenter + (mapPos + viewOffset) * zoom, Color.White, origin: new Vector2(256.0f, 256.0f), rotate: 0, scale: scale * zoom, spriteEffect: mapTiles[x, y].SpriteEffect); } } #if DEBUG if (generationParams.ShowNoiseMap) { GUI.DrawRectangle(spriteBatch, rectCenter + (borders.Location.ToVector2() + viewOffset) * zoom, borders.Size.ToVector2() * zoom, Color.White, true); } #endif Vector2 topLeft = rectCenter + viewOffset * zoom; topLeft.X = (int)topLeft.X; topLeft.Y = (int)topLeft.Y; Vector2 bottomRight = rectCenter + (viewOffset + new Vector2(size, size)) * zoom; bottomRight.X = (int)bottomRight.X; bottomRight.Y = (int)bottomRight.Y; spriteBatch.Draw(noiseTexture, destinationRectangle: new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)(bottomRight.X - topLeft.X), (int)(bottomRight.Y - topLeft.Y)), sourceRectangle: null, color: Color.White); if (topLeft.X > rect.X) { GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Y, (int)(topLeft.X - rect.X), rect.Height), Color.Black * 0.8f, true); } if (topLeft.Y > rect.Y) { GUI.DrawRectangle(spriteBatch, new Rectangle((int)topLeft.X, rect.Y, (int)(bottomRight.X - topLeft.X), (int)(topLeft.Y - rect.Y)), Color.Black * 0.8f, true); } if (bottomRight.X < rect.Right) { GUI.DrawRectangle(spriteBatch, new Rectangle((int)bottomRight.X, rect.Y, (int)(rect.Right - bottomRight.X), rect.Height), Color.Black * 0.8f, true); } if (bottomRight.Y < rect.Bottom) { GUI.DrawRectangle(spriteBatch, new Rectangle((int)topLeft.X, (int)bottomRight.Y, (int)(bottomRight.X - topLeft.X), (int)(rect.Bottom - bottomRight.Y)), Color.Black * 0.8f, true); } var sourceRect = rect; float rawNoiseScale = 1.0f + Noise[(int)(Timing.TotalTime * 100 % Noise.GetLength(0) - 1), (int)(Timing.TotalTime * 100 % Noise.GetLength(1) - 1)]; cameraNoiseStrength = Noise[(int)(Timing.TotalTime * 10 % Noise.GetLength(0) - 1), (int)(Timing.TotalTime * 10 % Noise.GetLength(1) - 1)]; rawNoiseSprite.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(), startOffset: new Point(Rand.Range(0, rawNoiseSprite.SourceRect.Width), Rand.Range(0, rawNoiseSprite.SourceRect.Height)), color: Color.White * cameraNoiseStrength * 0.5f, textureScale: Vector2.One * rawNoiseScale); rawNoiseSprite.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(), startOffset: new Point(Rand.Range(0, rawNoiseSprite.SourceRect.Width), Rand.Range(0, rawNoiseSprite.SourceRect.Height)), color: new Color(20, 20, 20, 100), textureScale: Vector2.One * rawNoiseScale * 2); if (generationParams.ShowLocations) { foreach (LocationConnection connection in connections) { Color connectionColor; if (GameMain.DebugDraw) { float sizeFactor = MathUtils.InverseLerp( MapGenerationParams.Instance.SmallLevelConnectionLength, MapGenerationParams.Instance.LargeLevelConnectionLength, connection.Length); connectionColor = ToolBox.GradientLerp(sizeFactor, Color.LightGreen, GUI.Style.Orange, GUI.Style.Red); } else { connectionColor = ToolBox.GradientLerp(connection.Difficulty / 100.0f, MapGenerationParams.Instance.LowDifficultyColor, MapGenerationParams.Instance.MediumDifficultyColor, MapGenerationParams.Instance.HighDifficultyColor); } int width = (int)(3 * zoom); if (SelectedLocation != CurrentLocation && (connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(CurrentLocation))) { connectionColor = Color.Gold; width *= 2; } else if (highlightedLocation != CurrentLocation && (connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(CurrentLocation))) { connectionColor = Color.Lerp(connectionColor, Color.White, 0.5f); width *= 2; } else if (!connection.Passed) { //crackColor *= 0.5f; } for (int i = 0; i < connection.CrackSegments.Count; i++) { var segment = connection.CrackSegments[i]; Vector2 start = rectCenter + (segment[0] + viewOffset) * zoom; Vector2 end = rectCenter + (segment[1] + viewOffset) * zoom; if (!rect.Contains(start) && !rect.Contains(end)) { continue; } else { if (MathUtils.GetLineRectangleIntersection(start, end, new Rectangle(rect.X, rect.Y + rect.Height, rect.Width, rect.Height), out Vector2 intersection)) { if (!rect.Contains(start)) { start = intersection; } else { end = intersection; } } } float distFromPlayer = Vector2.Distance(CurrentLocation.MapPosition, (segment[0] + segment[1]) / 2.0f); float dist = Vector2.Distance(start, end); float a = GameMain.DebugDraw ? 1.0f : (200.0f - distFromPlayer) / 200.0f; spriteBatch.Draw(generationParams.ConnectionSprite.Texture, new Rectangle((int)start.X, (int)start.Y, (int)(dist - 1 * zoom), width), null, connectionColor * MathHelper.Clamp(a, 0.1f, 0.5f), MathUtils.VectorToAngle(end - start), new Vector2(0, 16), SpriteEffects.None, 0.01f); } if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames) { Vector2 center = rectCenter + (connection.CenterPos + viewOffset) * zoom; if (rect.Contains(center)) { GUI.DrawString(spriteBatch, center, connection.Biome.Identifier + " (" + connection.Difficulty + ")", Color.White); } } } rect.Inflate(8, 8); GUI.DrawRectangle(spriteBatch, rect, Color.Black, false, 0.0f, 8); GUI.DrawRectangle(spriteBatch, rect, Color.LightGray); for (int i = 0; i < Locations.Count; i++) { Location location = Locations[i]; Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom; Rectangle drawRect = location.Type.Sprite.SourceRect; drawRect.X = (int)pos.X - drawRect.Width / 2; drawRect.Y = (int)pos.Y - drawRect.Width / 2; if (!rect.Intersects(drawRect)) { continue; } Color color = location.Type.SpriteColor; if (location.Connections.Find(c => c.Locations.Contains(CurrentLocation)) == null) { color *= 0.5f; } float iconScale = location == CurrentLocation ? 1.2f : 1.0f; if (location == highlightedLocation) { iconScale *= 1.1f; color = Color.Lerp(color, Color.White, 0.5f); } float distFromPlayer = Vector2.Distance(CurrentLocation.MapPosition, location.MapPosition); color *= MathHelper.Clamp((1000.0f - distFromPlayer) / 500.0f, 0.1f, 1.0f); location.Type.Sprite.Draw(spriteBatch, pos, color, scale: MapGenerationParams.Instance.LocationIconSize / location.Type.Sprite.size.X * iconScale * zoom); MapGenerationParams.Instance.LocationIndicator.Draw(spriteBatch, pos, color, scale: MapGenerationParams.Instance.LocationIconSize / MapGenerationParams.Instance.LocationIndicator.size.X * iconScale * zoom * 1.4f); } //PLACEHOLDER until the stuff at the center of the map is implemented float centerIconSize = 50.0f; Vector2 centerPos = rectCenter + (new Vector2(size / 2) + viewOffset) * zoom; bool mouseOn = Vector2.Distance(PlayerInput.MousePosition, centerPos) < centerIconSize * zoom; var centerLocationType = LocationType.List.Last(); Color centerColor = centerLocationType.SpriteColor * (mouseOn ? 1.0f : 0.6f); centerLocationType.Sprite.Draw(spriteBatch, centerPos, centerColor, scale: centerIconSize / centerLocationType.Sprite.size.X * zoom); MapGenerationParams.Instance.LocationIndicator.Draw(spriteBatch, centerPos, centerColor, scale: centerIconSize / MapGenerationParams.Instance.LocationIndicator.size.X * zoom * 1.2f); if (mouseOn && PlayerInput.PrimaryMouseButtonClicked() && !messageBoxOpen) { if (TextManager.ContainsTag("centerarealockedheader") && TextManager.ContainsTag("centerarealockedtext")) { var messageBox = new GUIMessageBox( TextManager.Get("centerarealockedheader"), TextManager.Get("centerarealockedtext")); messageBoxOpen = true; CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox)); } else { //if the message cannot be shown in the selected language, //show the campaign roadmap (which mentions the center location not being reachable) var messageBox = new GUIMessageBox(TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("CampaignRoadMapText")); messageBoxOpen = true; CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox)); } } } DrawDecorativeHUD(spriteBatch, rect); for (int i = 0; i < 2; i++) { Location location = (i == 0) ? highlightedLocation : CurrentLocation; if (location == null) { continue; } Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom; pos.X += 25 * zoom; pos.Y -= 5 * zoom; Vector2 size = GUI.LargeFont.MeasureString(location.Name); GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw( spriteBatch, new Rectangle((int)pos.X - 30, (int)(pos.Y - 10), (int)size.X + 60, (int)(size.Y + 50 * GUI.Scale)), Color.Black * hudOpenState * 0.7f); GUI.DrawString(spriteBatch, pos, location.Name, Color.White * hudOpenState * 1.5f, font: GUI.LargeFont); GUI.DrawString(spriteBatch, pos + Vector2.UnitY * size.Y * 0.8f, location.Type.Name, Color.White * hudOpenState * 1.5f); } spriteBatch.End(); GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect; spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable); }
public static void CreateItems(List <PurchasedItem> itemsToSpawn) { if (itemsToSpawn.Count == 0) { return; } WayPoint wp = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub); if (wp == null) { DebugConsole.ThrowError("The submarine must have a waypoint marked as Cargo for bought items to be placed correctly!"); return; } Hull cargoRoom = Hull.FindHull(wp.WorldPosition); if (cargoRoom == null) { DebugConsole.ThrowError("A waypoint marked as Cargo must be placed inside a room!"); return; } #if CLIENT new GUIMessageBox("", TextManager.GetWithVariable("CargoSpawnNotification", "[roomname]", cargoRoom.DisplayName, true), new string[0], type: GUIMessageBox.Type.InGame, iconStyle: "StoreShoppingCrateIcon"); #else foreach (Client client in GameMain.Server.ConnectedClients) { ChatMessage msg = ChatMessage.Create("", TextManager.ContainsTag(cargoRoom.RoomName) ? $"CargoSpawnNotification~[roomname]=§{cargoRoom.RoomName}" : $"CargoSpawnNotification~[roomname]={cargoRoom.RoomName}", ChatMessageType.ServerMessageBoxInGame, null); msg.IconStyle = "StoreShoppingCrateIcon"; GameMain.Server.SendDirectChatMessage(msg, client); } #endif List <ItemContainer> availableContainers = new List <ItemContainer>(); ItemPrefab containerPrefab = null; foreach (PurchasedItem pi in itemsToSpawn) { Vector2 position = GetCargoPos(cargoRoom, pi.ItemPrefab); for (int i = 0; i < pi.Quantity; i++) { ItemContainer itemContainer = null; if (!string.IsNullOrEmpty(pi.ItemPrefab.CargoContainerIdentifier)) { itemContainer = availableContainers.Find(ac => ac.Inventory.CanBePut(pi.ItemPrefab) && (ac.Item.Prefab.Identifier == pi.ItemPrefab.CargoContainerIdentifier || ac.Item.Prefab.Tags.Contains(pi.ItemPrefab.CargoContainerIdentifier.ToLowerInvariant()))); if (itemContainer == null) { containerPrefab = ItemPrefab.Prefabs.Find(ep => ep.Identifier == pi.ItemPrefab.CargoContainerIdentifier || (ep.Tags != null && ep.Tags.Contains(pi.ItemPrefab.CargoContainerIdentifier.ToLowerInvariant()))); if (containerPrefab == null) { DebugConsole.ThrowError("Cargo spawning failed - could not find the item prefab for container \"" + pi.ItemPrefab.CargoContainerIdentifier + "\"!"); continue; } Item containerItem = new Item(containerPrefab, position, wp.Submarine); itemContainer = containerItem.GetComponent <ItemContainer>(); if (itemContainer == null) { DebugConsole.ThrowError("Cargo spawning failed - container \"" + containerItem.Name + "\" does not have an ItemContainer component!"); continue; } availableContainers.Add(itemContainer); #if SERVER if (GameMain.Server != null) { Entity.Spawner.CreateNetworkEvent(itemContainer.Item, false); } #endif } } if (itemContainer == null) { //no container, place at the waypoint if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { Entity.Spawner.AddToSpawnQueue(pi.ItemPrefab, position, wp.Submarine, onSpawned: itemSpawned); } else { var item = new Item(pi.ItemPrefab, position, wp.Submarine); itemSpawned(item); } continue; } //place in the container if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { Entity.Spawner.AddToSpawnQueue(pi.ItemPrefab, itemContainer.Inventory, onSpawned: itemSpawned); } else { var item = new Item(pi.ItemPrefab, position, wp.Submarine); itemContainer.Inventory.TryPutItem(item, null); itemSpawned(item); }
public MissionPrefab(XElement element) { ConfigElement = element; Identifier = element.GetAttributeString("identifier", ""); TextIdentifier = element.GetAttributeString("textidentifier", null) ?? Identifier; tags = element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true); Name = TextManager.Get("MissionName." + TextIdentifier, true) ?? element.GetAttributeString("name", ""); Description = TextManager.Get("MissionDescription." + TextIdentifier, true) ?? element.GetAttributeString("description", ""); Reward = element.GetAttributeInt("reward", 1); AllowRetry = element.GetAttributeBool("allowretry", false); IsSideObjective = element.GetAttributeBool("sideobjective", false); RequireWreck = element.GetAttributeBool("requirewreck", false); Commonness = element.GetAttributeInt("commonness", 1); if (element.GetAttribute("difficulty") != null) { int difficulty = element.GetAttributeInt("difficulty", MinDifficulty); Difficulty = Math.Clamp(difficulty, MinDifficulty, MaxDifficulty); } SuccessMessage = TextManager.Get("MissionSuccess." + TextIdentifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully"); FailureMessage = TextManager.Get("MissionFailure." + TextIdentifier, true) ?? ""; if (string.IsNullOrEmpty(FailureMessage) && TextManager.ContainsTag("missionfailed")) { FailureMessage = TextManager.Get("missionfailed", returnNull: true) ?? ""; } if (string.IsNullOrEmpty(FailureMessage) && GameMain.Config.Language == "English") { FailureMessage = element.GetAttributeString("failuremessage", ""); } SonarLabel = TextManager.Get("MissionSonarLabel." + TextIdentifier, true) ?? TextManager.Get("MissionSonarLabel." + element.GetAttributeString("sonarlabel", ""), true) ?? element.GetAttributeString("sonarlabel", ""); SonarIconIdentifier = element.GetAttributeString("sonaricon", ""); MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false); SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false); AchievementIdentifier = element.GetAttributeString("achievementidentifier", ""); UnhideEntitySubCategories = element.GetAttributeStringArray("unhideentitysubcategories", new string[0]).ToList(); Headers = new List <string>(); Messages = new List <string>(); AllowedConnectionTypes = new List <Pair <string, string> >(); for (int i = 0; i < 100; i++) { string header = TextManager.Get("MissionHeader" + i + "." + TextIdentifier, true); string message = TextManager.Get("MissionMessage" + i + "." + TextIdentifier, true); if (!string.IsNullOrEmpty(message)) { Headers.Add(header); Messages.Add(message); } } int messageIndex = 0; foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "message": if (messageIndex > Headers.Count - 1) { Headers.Add(string.Empty); Messages.Add(string.Empty); } Headers[messageIndex] = TextManager.Get("MissionHeader" + messageIndex + "." + TextIdentifier, true) ?? subElement.GetAttributeString("header", ""); Messages[messageIndex] = TextManager.Get("MissionMessage" + messageIndex + "." + TextIdentifier, true) ?? subElement.GetAttributeString("text", ""); messageIndex++; break; case "locationtype": case "connectiontype": if (subElement.Attribute("identifier") != null) { AllowedLocationTypes.Add(subElement.GetAttributeString("identifier", "")); } else { AllowedConnectionTypes.Add(new Pair <string, string>( subElement.GetAttributeString("from", ""), subElement.GetAttributeString("to", ""))); } break; case "locationtypechange": LocationTypeChangeOnCompleted = new LocationTypeChange(subElement.GetAttributeString("from", ""), subElement, requireChangeMessages: false, defaultProbability: 1.0f); break; case "reputation": case "reputationreward": string factionIdentifier = subElement.GetAttributeString("identifier", ""); float amount = subElement.GetAttributeFloat("amount", 0.0f); if (ReputationRewards.ContainsKey(factionIdentifier)) { DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Multiple reputation changes defined for the identifier \"{factionIdentifier}\"."); continue; } ReputationRewards.Add(factionIdentifier, amount); if (!factionIdentifier.Equals("location", StringComparison.OrdinalIgnoreCase)) { if (FactionPrefab.Prefabs != null && !FactionPrefab.Prefabs.Any(p => p.Identifier.Equals(factionIdentifier, StringComparison.OrdinalIgnoreCase))) { DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Could not find a faction with the identifier \"{factionIdentifier}\"."); } } break; case "metadata": string identifier = subElement.GetAttributeString("identifier", string.Empty); string stringValue = subElement.GetAttributeString("value", string.Empty); if (!string.IsNullOrWhiteSpace(stringValue) && !string.IsNullOrWhiteSpace(identifier)) { object value = SetDataAction.ConvertXMLValue(stringValue); SetDataAction.OperationType operation = SetDataAction.OperationType.Set; string operatingString = subElement.GetAttributeString("operation", string.Empty); if (!string.IsNullOrWhiteSpace(operatingString)) { operation = (SetDataAction.OperationType)Enum.Parse(typeof(SetDataAction.OperationType), operatingString); } DataRewards.Add(Tuple.Create(identifier, value, operation)); } break; case "triggerevent": TriggerEvents.Add(new TriggerEvent(subElement)); break; } } string missionTypeName = element.GetAttributeString("type", ""); //backwards compatibility if (missionTypeName.Equals("outpostdestroy", StringComparison.OrdinalIgnoreCase) || missionTypeName.Equals("outpostrescue", StringComparison.OrdinalIgnoreCase)) { missionTypeName = "AbandonedOutpost"; } if (!Enum.TryParse(missionTypeName, out Type)) { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - \"" + missionTypeName + "\" is not a valid mission type."); return; } if (Type == MissionType.None) { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - mission type cannot be none."); return; } if (CoOpMissionClasses.ContainsKey(Type)) { constructor = CoOpMissionClasses[Type].GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]), typeof(Submarine) }); } else if (PvPMissionClasses.ContainsKey(Type)) { constructor = PvPMissionClasses[Type].GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]), typeof(Submarine) }); } else { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - unsupported mission type \"" + Type.ToString() + "\""); } if (constructor == null) { DebugConsole.ThrowError($"Failed to find a constructor for the mission type \"{Type}\"!"); } InitProjSpecific(element); }
public MissionPrefab(XElement element) { ConfigElement = element; Identifier = element.GetAttributeString("identifier", ""); TextIdentifier = element.GetAttributeString("textidentifier", null) ?? Identifier; tags = element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true); Name = TextManager.Get("MissionName." + TextIdentifier, true) ?? element.GetAttributeString("name", ""); Description = TextManager.Get("MissionDescription." + TextIdentifier, true) ?? element.GetAttributeString("description", ""); Reward = element.GetAttributeInt("reward", 1); Commonness = element.GetAttributeInt("commonness", 1); SuccessMessage = TextManager.Get("MissionSuccess." + TextIdentifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully"); FailureMessage = TextManager.Get("MissionFailure." + TextIdentifier, true) ?? ""; if (string.IsNullOrEmpty(FailureMessage) && TextManager.ContainsTag("missionfailed")) { FailureMessage = TextManager.Get("missionfailed", returnNull: true) ?? ""; } if (string.IsNullOrEmpty(FailureMessage) && GameMain.Config.Language == "English") { FailureMessage = element.GetAttributeString("failuremessage", ""); } SonarLabel = TextManager.Get("MissionSonarLabel." + TextIdentifier, true) ?? element.GetAttributeString("sonarlabel", ""); SonarIconIdentifier = element.GetAttributeString("sonaricon", ""); MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false); SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false); AchievementIdentifier = element.GetAttributeString("achievementidentifier", ""); Headers = new List <string>(); Messages = new List <string>(); AllowedLocationTypes = new List <Pair <string, string> >(); foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "message": int index = Messages.Count; Headers.Add(TextManager.Get("MissionHeader" + index + "." + TextIdentifier, true) ?? subElement.GetAttributeString("header", "")); Messages.Add(TextManager.Get("MissionMessage" + index + "." + TextIdentifier, true) ?? subElement.GetAttributeString("text", "")); break; case "locationtype": AllowedLocationTypes.Add(new Pair <string, string>( subElement.GetAttributeString("from", ""), subElement.GetAttributeString("to", ""))); break; case "reputation": case "reputationreward": string factionIdentifier = subElement.GetAttributeString("identifier", ""); float amount = subElement.GetAttributeFloat("amount", 0.0f); if (ReputationRewards.ContainsKey(factionIdentifier)) { DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Multiple reputation changes defined for the identifier \"{factionIdentifier}\"."); continue; } ReputationRewards.Add(factionIdentifier, amount); if (!factionIdentifier.Equals("location", StringComparison.OrdinalIgnoreCase)) { if (FactionPrefab.Prefabs != null && !FactionPrefab.Prefabs.Any(p => p.Identifier.Equals(factionIdentifier, StringComparison.OrdinalIgnoreCase))) { DebugConsole.ThrowError($"Error in mission prefab \"{Identifier}\". Could not find a faction with the identifier \"{factionIdentifier}\"."); } } break; case "metadata": string identifier = subElement.GetAttributeString("identifier", string.Empty); string stringValue = subElement.GetAttributeString("value", string.Empty); if (!string.IsNullOrWhiteSpace(stringValue) && !string.IsNullOrWhiteSpace(identifier)) { object value = SetDataAction.ConvertXMLValue(stringValue); SetDataAction.OperationType operation = SetDataAction.OperationType.Set; string operatingString = subElement.GetAttributeString("operation", string.Empty); if (!string.IsNullOrWhiteSpace(operatingString)) { operation = (SetDataAction.OperationType)Enum.Parse(typeof(SetDataAction.OperationType), operatingString); } DataRewards.Add(Tuple.Create(identifier, value, operation)); } break; } } string missionTypeName = element.GetAttributeString("type", ""); if (!Enum.TryParse(missionTypeName, out Type)) { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - \"" + missionTypeName + "\" is not a valid mission type."); return; } if (Type == MissionType.None) { DebugConsole.ThrowError("Error in mission prefab \"" + Name + "\" - mission type cannot be none."); return; } constructor = missionClasses[Type].GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) }); InitProjSpecific(element); }