1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
4 using System.Collections.Generic;
5 using System.Collections.Immutable;
6 using System.Globalization;
13 private float crewListAnimDelay = 0.25f;
14 private float missionIconAnimDelay;
16 private const float jobColumnWidthPercentage = 0.11f;
17 private const float characterColumnWidthPercentage = 0.44f;
18 private const float statusColumnWidthPercentage = 0.45f;
20 private int jobColumnWidth, characterColumnWidth, statusColumnWidth;
22 private readonly List<Mission> selectedMissions;
23 private readonly
Location startLocation, endLocation;
27 private readonly Dictionary<Identifier, float> initialFactionReputations =
new Dictionary<Identifier, float>();
37 this.gameMode = gameMode;
38 this.selectedMissions = selectedMissions.ToList();
39 this.startLocation = startLocation;
40 this.endLocation = endLocation;
43 foreach (
Faction faction
in campaignMode.Factions)
60 SoundPlayer.OverrideMusicType = (gameOver ?
"crewdead" :
"endround").ToIdentifier();
61 SoundPlayer.OverrideMusicDuration = 18.0f;
69 List<GUIComponent> rightPanels =
new List<GUIComponent>();
71 int minWidth = 400, minHeight = 350;
72 int padding = GUI.IntScale(25.0f);
85 TextManager.Get(
"crew"), textAlignment: Alignment.
TopLeft, font: GUIStyle.SubHeadingFont);
86 crewHeader.RectTransform.MinSize =
new Point(0, GUI.IntScale(crewHeader.Rect.Height * 2.0f));
89 if (traitorResults !=
null && traitorResults.Value.VotedAsTraitorClientSessionId > 0)
91 var traitorInfoPanel = CreateTraitorInfoPanel(crewList.Content, traitorResults.Value, crewListAnimDelay);
92 traitorInfoPanel.RectTransform.SetAsFirstChild();
93 var spacing =
new GUIFrame(
new RectTransform(
new Point(0, GUI.IntScale(20)), crewList.Content.RectTransform), style:
null);
94 spacing.RectTransform.RepositionChildInHierarchy(1);
102 rightPanels.Add(crewFrame2);
110 crewHeader2.RectTransform.MinSize =
new Point(0, GUI.IntScale(crewHeader2.Rect.Height * 2.0f));
118 if (!headerText.IsNullOrEmpty())
121 headerText, textAlignment: Alignment.BottomLeft, font: GUIStyle.LargeFont, wrap:
true);
127 if (campaignMode !=
null)
130 rightPanels.Add(reputationframe);
139 TextManager.Get(
"reputation"), textAlignment: Alignment.
TopLeft, font: GUIStyle.SubHeadingFont);
140 reputationHeader.RectTransform.MinSize =
new Point(0, GUI.IntScale(reputationHeader.Rect.Height * 2.0f));
151 RelativeSpacing = 0.03f
160 List<Mission> missionsToDisplay =
new List<Mission>(selectedMissions.Where(m => m.Prefab.ShowInMenus));
161 if (startLocation !=
null)
163 foreach (
Mission mission
in startLocation.SelectedMissions)
165 if (missionsToDisplay.Contains(mission)) {
continue; }
168 mission.
Locations.Contains(campaignMode?.Map.SelectedLocation))
170 missionsToDisplay.Add(mission);
177 Spacing = GUI.IntScale(15)
183 RelativeSpacing = 0.025f
187 missionContent.Recalculate();
189 if (!
string.IsNullOrWhiteSpace(endMessage))
192 TextManager.GetServerMessage(endMessage), wrap:
true)
198 float animDelay = missionIconAnimDelay;
199 foreach (
Mission mission
in missionsToDisplay)
201 var textContent =
new List<LocalizedString>();
203 if (selectedMissions.Contains(mission))
208 if (!repText.IsNullOrEmpty()) { textContent.Add(repText); }
219 string shareFormatted =
string.Format(CultureInfo.InvariantCulture,
"{0:N0}", share);
220 RichString yourShareString = TextManager.GetWithVariables(
"crewwallet.missionreward.get", (
"[money]", $
"{shareFormatted}"), (
"[share]", $
"{percentage}"));
221 textContent.Add(yourShareString);
229 if (!repText.IsNullOrEmpty()) { textContent.Add(repText); }
243 if (selectedMissions.Contains(mission))
250 if (!missionsToDisplay.Any())
254 RelativeSpacing = 0.025f,
258 GUIImage missionIcon =
new GUIImage(
new RectTransform(
new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), style:
"NoMissionIcon", scaleToFit:
true);
260 TextManager.Get(
"nomission"), font: GUIStyle.LargeFont);
263 gameSession?.EventManager?.EventLog?.CreateEventLogUI(missionList.Content, traitorResults);
271 missionFrameContent.Recalculate();
275 int panelSpacing = GUI.IntScale(20);
276 int totalHeight = crewFrame.Rect.Height + panelSpacing + missionframe.Rect.Height;
277 int totalWidth = crewFrame.Rect.Width;
280 missionframe.RectTransform.AbsoluteOffset =
new Point(0, crewFrame.Rect.Bottom + panelSpacing);
282 if (rightPanels.Any())
284 totalWidth = crewFrame.Rect.Width * 2 + panelSpacing;
285 if (headerTextBlock !=
null)
287 headerTextBlock.RectTransform.MinSize =
new Point(totalWidth, 0);
289 crewFrame.RectTransform.AbsoluteOffset =
new Point(-(crewFrame.Rect.Width + panelSpacing) / 2, crewFrame.RectTransform.AbsoluteOffset.Y);
290 foreach (var rightPanel
in rightPanels)
292 rightPanel.RectTransform.AbsoluteOffset =
new Point((rightPanel.Rect.Width + panelSpacing) / 2, crewFrame.RectTransform.AbsoluteOffset.Y);
305 foreach (
Faction faction
in campaignMode.Factions.OrderBy(f => f.Prefab.MenuOrder).ThenBy(f => f.Prefab.Name))
308 if (!initialFactionReputations.TryGetValue(faction.
Prefab.Identifier, out initialReputation))
310 DebugConsole.AddWarning($
"Could not determine reputation change for faction \"{faction.Prefab.Name}\" (faction was not present at the start of the round).");
312 var factionFrame = CreateReputationElement(
313 reputationList.Content,
316 faction.
Prefab.ShortDescription, faction.
Prefab.Description,
318 CreatePathUnlockElement(factionFrame, faction,
null);
321 float maxDescriptionHeight = 0.0f;
325 float descriptionHeight = descriptionElement.
TextSize.Y * 1.1f;
328 descriptionHeight += 1.25f * unlockInfoComponent.Rect.Height;
330 maxDescriptionHeight = Math.Max(maxDescriptionHeight, descriptionHeight);
337 descriptionElement.RectTransform.IsFixedSize =
true;
338 child.
RectTransform.
NonScaledSize =
new Point(child.
Rect.Width, headerElement.Rect.Height + descriptionElement.RectTransform.Parent.Children.Sum(c => c.Rect.Height + ((
GUILayoutGroup)descriptionElement.Parent).AbsoluteSpacing));
345 IEnumerable<LocationConnection> connectionsBetweenBiomes =
353 if (connectionsBetweenBiomes.Where(c => !c.Locked).Any(c =>
363 if (unlockEvent ==
null) {
continue; }
364 if (unlockEvent.Faction.IsEmpty)
366 if (location ==
null || gateLocation != location) {
continue; }
370 if (faction ==
null || faction.
Prefab.Identifier != unlockEvent.Faction) {
continue; }
373 if (unlockEvent !=
null)
377 if (!unlockEvent.Faction.IsEmpty)
382 float normalizedUnlockReputation = MathUtils.InverseLerp(unlockReputation.
MinReputation, unlockReputation.
MaxReputation, unlockEvent.UnlockPathReputation);
384 "lockedpathreputationrequirement",
386 (
"[biomename]", $
"‖color:gui.orange‖{connection.LevelData.Biome.DisplayName}‖end‖")));
387 var unlockInfoPanel =
new GUITextBlock(
new RectTransform(
new Vector2(0.8f, 0.0f), reputationFrame.
RectTransform,
Anchor.BottomCenter) { MinSize = new Point(0, GUI.IntScale(30)), AbsoluteOffset = new Point(0, GUI.IntScale(3)) },
388 unlockText, style:
"GUIButtonRound", textAlignment: Alignment.Center, textColor: GUIStyle.TextColorNormal);
389 unlockInfoPanel.Color = Color.Lerp(unlockInfoPanel.Color, Color.Black, 0.8f);
390 unlockInfoPanel.UserData =
"unlockinfo";
391 if (unlockInfoPanel.TextSize.X > unlockInfoPanel.Rect.Width * 0.7f)
393 unlockInfoPanel.Font = GUIStyle.SmallFont;
402 var traitorCharacter = traitorResults.GetTraitorClient()?.Character;
405 traitorResults.VotedCorrectTraitor ?
406 traitorResults.ObjectiveSuccessful ?
"traitor.blameresult.correct.objectivesuccessful" :
"traitor.blameresult.correct.objectivefailed" :
407 "traitor.blameresult.failure";
409 var textContent =
new List<LocalizedString>()
411 TextManager.GetWithVariable(
"traitor.blameresult",
"[name]", traitorCharacter?.Name ??
"unknown"),
412 TextManager.Get(resultTag)
415 if (traitorResults.MoneyPenalty > 0)
418 TextManager.GetWithVariable(
419 "traitor.blameresult.failure.penalty",
421 TextManager.FormatCurrency(traitorResults.MoneyPenalty, includeCurrencySymbol:
false)));
424 var icon = GUIStyle.GetComponentStyle(
"TraitorMissionIcon")?.GetDefaultSprite();
430 difficultyIconCount: 0,
432 out GUIImage missionIcon);
440 int spacing = GUI.IntScale(5);
445 int iconSize = (int)(GUIStyle.SubHeadingFont.MeasureChar(
'T').Y + defaultLineHeight * 6);
450 AbsoluteSpacing = spacing,
458 HoverColor = iconColor,
459 SelectedColor = iconColor,
470 AbsoluteSpacing = spacing
475 List<RichString> contentStrings =
new List<RichString>(textContent.Select(t =>
RichString.
Rich(t)));
477 if (!header.IsNullOrEmpty())
480 missionNameString, font: GUIStyle.SubHeadingFont, wrap:
true);
481 nameText.RectTransform.MinSize =
new Point(0, (
int)nameText.TextSize.Y);
485 if (difficultyIconCount > 0)
493 for (
int i = 0; i < difficultyIconCount; i++)
497 CanBeFocused =
false,
498 Color = difficultyColor
504 foreach (var contentString
in contentStrings)
506 var text =
new GUITextBlock(
new RectTransform(
new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), contentString, wrap:
true);
507 text.RectTransform.MinSize =
new Point(0, (
int)text.TextSize.Y);
508 firstContentText ??= text;
510 if (difficultyIndicatorGroup !=
null && firstContentText !=
null)
513 difficultyIndicatorGroup.RectTransform.AbsoluteOffset =
new Point((
int)firstContentText.Padding.X, 0);
515 missionTextGroup.RectTransform.MinSize =
516 new Point(0, missionTextGroup.Children.Sum(c => c.Rect.Height + missionTextGroup.AbsoluteSpacing) - missionTextGroup.AbsoluteSpacing);
517 missionTextGroup.Recalculate();
518 content.RectTransform.MinSize =
new Point(0, Math.Max(missionTextGroup.Rect.Height, iconSize));
525 var children = container.
Children.ToList();
526 if (children.Count < 2) {
return; }
528 var lastChild = children.Last();
529 foreach (var child
in children)
531 if (child != lastChild)
533 var separator =
new GUIFrame(
new RectTransform(
new Vector2(0.5f, 0.1f), container.RectTransform), style:
"HorizontalLine");
534 separator.RectTransform.RepositionChildInHierarchy(container.GetChildIndex(child) + 1);
541 if (missionIcon ==
null) {
return; }
542 string style = success ?
"MissionCompletedIcon" :
"MissionFailedIcon";
544 if (
string.IsNullOrEmpty(style))
546 if (stateIcon !=
null)
553 bool wasVisible = stateIcon is { Visible:
true };
558 stateIcon.
FadeIn(delay, 0.15f);
559 stateIcon.
Pulsate(Vector2.One, Vector2.One * 1.5f, 1.0f + delay);
572 textTag =
"RoundSummaryGameOver";
576 switch (transitionType)
578 case CampaignMode.TransitionType.LeaveLocation:
579 locationName = startLocation?.DisplayName;
580 textTag =
"RoundSummaryLeaving";
582 case CampaignMode.TransitionType.ProgressToNextLocation:
583 locationName = endLocation?.DisplayName;
584 textTag =
"RoundSummaryProgress";
586 case CampaignMode.TransitionType.ProgressToNextEmptyLocation:
587 locationName = endLocation?.DisplayName;
588 textTag =
"RoundSummaryProgressToEmptyLocation";
590 case CampaignMode.TransitionType.ReturnToPreviousLocation:
591 locationName = startLocation?.DisplayName;
592 textTag =
"RoundSummaryReturn";
594 case CampaignMode.TransitionType.ReturnToPreviousEmptyLocation:
595 locationName = startLocation?.DisplayName;
596 textTag =
"RoundSummaryReturnToEmptyLocation";
599 textTag =
Submarine.MainSub.AtEndExit ?
"RoundSummaryProgress" :
"RoundSummaryReturn";
604 if (startLocation?.Biome !=
null && startLocation.Biome.IsEndBiome)
606 locationName ??= startLocation.DisplayName;
609 if (textTag ==
null) {
return ""; }
611 if (locationName ==
null)
613 DebugConsole.ThrowError($
"Error while creating round summary: could not determine destination location. Start location: {startLocation?.DisplayName ?? "null"}, end location: {endLocation?.DisplayName ?? "null"}");
614 locationName =
"[UNKNOWN]";
617 LocalizedString subName =
string.Empty;
618 SubmarineInfo currentOrPending = SubmarineSelection.CurrentOrPendingSubmarine();
619 if (currentOrPending !=
null)
621 subName = currentOrPending.DisplayName;
624 return TextManager.GetWithVariables(textTag, (
"[sub]", subName), (
"[location]", locationName));
627 private GUIListBox CreateCrewList(GUIComponent parent, IEnumerable<CharacterInfo> characterInfos, TraitorManager.TraitorResults? traitorResults)
629 var headerFrame =
new GUILayoutGroup(
new RectTransform(
new Vector2(1.0f, 0.0f), parent.RectTransform,
Anchor.TopCenter, minSize:
new Point(0, (
int)(30 * GUI.Scale))) { }, isHorizontal:
true)
633 GUIButton jobButton =
new GUIButton(
new RectTransform(
new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get(
"tabmenu.job"), style:
"GUIButtonSmallFreeScale");
634 GUIButton characterButton =
new GUIButton(
new RectTransform(
new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get(
"name"), style:
"GUIButtonSmallFreeScale");
635 GUIButton statusButton =
new GUIButton(
new RectTransform(
new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get(
"label.statuslabel"), style:
"GUIButtonSmallFreeScale");
637 float sizeMultiplier = 1.0f;
640 jobButton.RectTransform.RelativeSize =
new Vector2(jobColumnWidthPercentage * sizeMultiplier, 1f);
641 characterButton.RectTransform.RelativeSize =
new Vector2(characterColumnWidthPercentage * sizeMultiplier, 1f);
642 statusButton.RectTransform.RelativeSize =
new Vector2(statusColumnWidthPercentage * sizeMultiplier, 1f);
644 jobButton.TextBlock.Font = characterButton.TextBlock.Font = statusButton.TextBlock.Font = GUIStyle.HotkeyFont;
645 jobButton.CanBeFocused = characterButton.CanBeFocused = statusButton.CanBeFocused =
false;
646 jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = statusButton.ForceUpperCase =
ForceUpperCase.Yes;
648 jobColumnWidth = jobButton.Rect.Width;
649 characterColumnWidth = characterButton.Rect.Width;
650 statusColumnWidth = statusButton.Rect.Width;
652 GUIListBox crewList =
new GUIListBox(
new RectTransform(Vector2.One, parent.RectTransform))
654 Padding =
new Vector4(4, 10, 0, 0) * GUI.Scale,
655 AutoHideScrollBar =
false
657 crewList.ContentBackground.Color = Color.Transparent;
659 headerFrame.RectTransform.RelativeSize -=
new Vector2(crewList.ScrollBar.RectTransform.RelativeSize.X, 0.0f);
661 float delay = crewListAnimDelay;
662 foreach (CharacterInfo characterInfo
in characterInfos)
664 if (characterInfo ==
null) {
continue; }
665 CreateCharacterElement(characterInfo, crewList, traitorResults, delay);
666 delay += crewListAnimDelay;
668 missionIconAnimDelay = delay;
673 private void CreateCharacterElement(CharacterInfo characterInfo, GUIListBox listBox, TraitorManager.TraitorResults? traitorResults,
float animDelay)
675 GUIFrame frame =
new GUIFrame(
new RectTransform(
new Point(listBox.Content.Rect.Width, GUI.IntScale(45)), listBox.Content.RectTransform), style:
"ListBoxElement")
677 CanBeFocused =
false,
678 UserData = characterInfo,
679 Color = (
Character.Controlled?.Info == characterInfo) ? TabMenu.OwnCharacterBGColor : Color.Transparent
682 var paddedFrame =
new GUILayoutGroup(
new RectTransform(
new Vector2(1.0f, 0.9f), frame.RectTransform,
Anchor.Center), isHorizontal:
true)
688 new GUICustomComponent(
new RectTransform(
new Point(jobColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform,
Anchor.Center), onDraw: (sb, component) => characterInfo.DrawJobIcon(sb, component.Rect))
690 ToolTip = characterInfo.Job.Name ??
"",
691 HoverColor = Color.White,
692 SelectedColor = Color.White
695 GUITextBlock characterNameBlock =
new GUITextBlock(
new RectTransform(
new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
696 ToolBox.LimitString(characterInfo.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: characterInfo.Job.Prefab.UIColor);
698 LocalizedString statusText = TextManager.Get(
"StatusOK");
699 Color statusColor = GUIStyle.Green;
701 Character character = characterInfo.Character;
702 if (character ==
null || character.IsDead)
704 if (character ==
null && characterInfo.IsNewHire && characterInfo.CauseOfDeath ==
null)
706 statusText = TextManager.Get(
"CampaignCrew.NewHire");
707 statusColor = GUIStyle.Blue;
709 else if (characterInfo.CauseOfDeath ==
null)
711 statusText = TextManager.Get(
"CauseOfDeathDescription.Unknown");
712 statusColor = Color.DarkRed;
714 else if (characterInfo.CauseOfDeath.Type ==
CauseOfDeathType.Affliction && characterInfo.CauseOfDeath.Affliction ==
null)
716 string errorMsg =
"Character \"[name]\" had an invalid cause of death (the type of the cause of death was Affliction, but affliction was not specified).";
717 DebugConsole.ThrowError(errorMsg.Replace(
"[name]", characterInfo.Name));
718 GameAnalyticsManager.AddErrorEventOnce(
"RoundSummary:InvalidCauseOfDeath", GameAnalyticsManager.ErrorSeverity.Error, errorMsg.Replace(
"[name]", characterInfo.SpeciesName.Value));
719 statusText = TextManager.Get(
"CauseOfDeathDescription.Unknown");
720 statusColor = GUIStyle.Red;
724 statusText = characterInfo.CauseOfDeath.Type ==
CauseOfDeathType.Affliction ?
725 characterInfo.CauseOfDeath.Affliction.CauseOfDeathDescription :
726 TextManager.Get(
"CauseOfDeathDescription." + characterInfo.CauseOfDeath.Type.ToString());
727 statusColor = Color.DarkRed;
732 if (character.IsUnconscious)
734 statusText = TextManager.Get(
"Unconscious");
735 statusColor = Color.DarkOrange;
737 else if (character.Vitality / character.MaxVitality < 0.8f)
739 statusText = TextManager.Get(
"Injured");
740 statusColor = Color.DarkOrange;
744 GUITextBlock statusBlock =
new GUITextBlock(
new RectTransform(
new Point(statusColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
745 ToolBox.LimitString(statusText.Value, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: statusColor);
747 frame.FadeIn(animDelay, 0.15f);
748 foreach (var child
in frame.GetAllChildren())
750 child.FadeIn(animDelay, 0.15f);
753 if (traitorResults.HasValue && GameMain.NetworkMember !=
null)
755 var clientVotedAsTraitor = traitorResults.Value.GetTraitorClient();
756 bool isTraitor = clientVotedAsTraitor !=
null && clientVotedAsTraitor.Character == character;
759 var img =
new GUIImage(
new RectTransform(
new Point(paddedFrame.Rect.Height), paddedFrame.RectTransform,
Anchor.CenterRight), style:
"TraitorVoteButton")
761 IgnoreLayoutGroups =
true,
762 ToolTip = TextManager.GetWithVariable(
"traitor.blameresult",
"[name]", characterInfo.Name)
764 img.FadeIn(1.0f + animDelay, 0.15f);
765 img.Pulsate(Vector2.One, Vector2.One * 1.5f, 1.5f + animDelay);
770 private static GUIFrame CreateReputationElement(GUIComponent parent,
771 LocalizedString name, Reputation reputation,
float initialReputation,
772 LocalizedString shortDescription, LocalizedString fullDescription, Sprite icon, Sprite backgroundPortrait, Color iconColor)
774 var factionFrame =
new GUIFrame(
new RectTransform(
new Vector2(1.0f, 0.1f), parent.RectTransform), style:
null);
776 if (backgroundPortrait !=
null)
778 new GUICustomComponent(
new RectTransform(Vector2.One, factionFrame.RectTransform), onDraw: (sb, customComponent) =>
780 backgroundPortrait.Draw(sb, customComponent.Rect.Center.ToVector2(), customComponent.Color, backgroundPortrait.size / 2, scale: customComponent.Rect.Width / backgroundPortrait.size.X);
783 HideElementsOutsideFrame =
true,
784 IgnoreLayoutGroups =
true,
785 Color = iconColor * 0.2f
789 var factionInfoHorizontal =
new GUILayoutGroup(
new RectTransform(
new Vector2(0.95f, 0.9f), factionFrame.RectTransform,
Anchor.Center), childAnchor:
Anchor.CenterRight, isHorizontal:
true)
791 AbsoluteSpacing = GUI.IntScale(5),
795 var factionIcon =
new GUIImage(
new RectTransform(Vector2.One * 0.7f, factionInfoHorizontal.RectTransform, scaleBasis:
ScaleBasis.Smallest), icon, scaleToFit:
true)
799 var factionTextContent =
new GUILayoutGroup(
new RectTransform(Vector2.One, factionInfoHorizontal.RectTransform))
801 AbsoluteSpacing = GUI.IntScale(10),
805 factionInfoHorizontal.Recalculate();
807 var header =
new GUITextBlock(
new RectTransform(
new Point(factionTextContent.Rect.Width, GUI.IntScale(40)), factionTextContent.RectTransform),
808 name, font: GUIStyle.SubHeadingFont)
810 Padding = Vector4.Zero,
813 header.RectTransform.IsFixedSize =
true;
815 var sliderHolder =
new GUILayoutGroup(
new RectTransform(
new Point((
int)(factionTextContent.Rect.Width * 0.8f), GUI.IntScale(20.0f)), factionTextContent.RectTransform),
816 childAnchor:
Anchor.CenterLeft, isHorizontal:
true)
818 RelativeSpacing = 0.05f,
821 sliderHolder.RectTransform.IsFixedSize =
true;
822 factionTextContent.Recalculate();
824 new GUICustomComponent(
new RectTransform(
new Vector2(0.8f, 1.0f), sliderHolder.RectTransform),
825 onDraw: (sb, customComponent) =>
DrawReputationBar(sb, customComponent.Rect, reputation.NormalizedValue, reputation.MinReputation, reputation.MaxReputation));
827 var reputationText =
new GUITextBlock(
new RectTransform(
new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
828 string.Empty, textAlignment: Alignment.CenterLeft, font: GUIStyle.SubHeadingFont);
829 SetReputationText(reputationText);
830 reputation?.OnReputationValueChanged.RegisterOverwriteExisting(
"RefreshRoundSummary".ToIdentifier(), _ =>
832 SetReputationText(reputationText);
835 void SetReputationText(GUITextBlock textBlock)
837 LocalizedString reputationText = Reputation.GetFormattedReputationText(reputation.NormalizedValue, reputation.Value, addColorTags:
true);
838 int reputationChange = (int)Math.Round(reputation.Value - initialReputation);
839 if (Math.Abs(reputationChange) > 0)
841 string changeText = $
"{(reputationChange > 0 ? "+
" : "") + reputationChange}";
842 string colorStr = XMLExtensions.ToStringHex(reputationChange > 0 ? GUIStyle.Green : GUIStyle.Red);
843 textBlock.Text = RichString.Rich($
"{reputationText} (‖color:{colorStr}‖{changeText}‖color:end‖)");
847 textBlock.Text = RichString.Rich(reputationText);
852 new GUIFrame(
new RectTransform(
new Vector2(1.0f, 0.0f), factionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(5)) }, style:
null);
854 var factionDescription =
new GUITextBlock(
new RectTransform(
new Vector2(0.8f, 0.6f), factionTextContent.RectTransform),
855 shortDescription, font: GUIStyle.SmallFont, wrap:
true)
857 UserData =
"description",
858 Padding = Vector4.Zero
860 if (shortDescription != fullDescription && !fullDescription.IsNullOrEmpty())
862 factionDescription.ToolTip = fullDescription;
866 new GUIFrame(
new RectTransform(
new Vector2(1.0f, 0.0f), factionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(5)) }, style:
null);
868 factionInfoHorizontal.Recalculate();
869 factionTextContent.Recalculate();
874 public static void DrawReputationBar(SpriteBatch sb, Rectangle rect,
float normalizedReputation,
float minReputation,
float maxReputation)
876 int segmentWidth = rect.Width / 5;
877 rect.Width = segmentWidth * 5;
878 for (
int i = 0; i < 5; i++)
881 GUI.DrawRectangle(sb,
new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), GUIStyle.ColorInventoryBackground, isFilled:
false);
883 GUI.DrawRectangle(sb, rect, GUIStyle.ColorInventoryBackground, isFilled:
false);
885 GUI.Arrow.Draw(sb,
new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUIStyle.ColorInventoryBackground, scale: GUI.Scale, spriteEffect: SpriteEffects.FlipVertically);
886 GUI.Arrow.Draw(sb,
new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUIStyle.TextColorNormal, scale: GUI.Scale * 0.8f, spriteEffect: SpriteEffects.FlipVertically);
888 GUI.DrawString(sb,
new Vector2(rect.X, rect.Bottom), ((
int)minReputation).ToString(), GUIStyle.TextColorNormal, font: GUIStyle.SmallFont);
889 string maxRepText = ((int)maxReputation).ToString();
890 Vector2 textSize = GUIStyle.SmallFont.MeasureString(maxRepText);
891 GUI.DrawString(sb,
new Vector2(rect.Right - textSize.X, rect.Bottom), maxRepText, GUIStyle.TextColorNormal, font: GUIStyle.SmallFont);
Biome(ContentXElement element, LevelGenerationParametersFile file)
IReadOnlyList< Faction > Factions
static Character? Controlled
static LocalizedString GetTeamName(CharacterTeamType teamID)
IEnumerable< Character > GetCharacters()
IEnumerable< CharacterInfo > GetCharacterInfos()
Note: this only returns AI characters' infos in multiplayer. The infos are used to manage hiring/firi...
static EventPrefab GetUnlockPathEvent(Identifier biomeIdentifier, Faction faction)
GUIComponent GetChild(int index)
void Pulsate(Vector2 startScale, Vector2 endScale, float duration)
GUIComponent FindChild(Func< GUIComponent, bool > predicate, bool recursive=false)
void FadeIn(float wait, float duration, bool alsoChildren=false)
RectTransform RectTransform
IEnumerable< GUIComponent > Children
Vector2 MeasureChar(char c)
GUIFrame ContentBackground
A frame drawn behind the content of the listbox
GUIFrame Content
A frame that contains the contents of the listbox. The frame itself is not rendered.
static GameSession?? GameSession
static int GraphicsHeight
static bool IsMultiplayer
static NetworkMember NetworkMember
static ImmutableHashSet< Character > GetSessionCrewCharacters(CharacterType type)
Returns a list of crew characters currently in the game with a given filter.
IEnumerable< Mission > Missions
List< LocationConnection > Connections
Color GetDifficultyColor()
virtual LocalizedString FailureMessage
readonly MissionPrefab Prefab
virtual RichString GetMissionRewardText(Submarine sub)
Returns the full reward text of the mission (e.g. "Reward: 2,000 mk" or "Reward: 500 mk x 2 (out of m...
IEnumerable< LocalizedString > ShownMessages
virtual LocalizedString Name
virtual LocalizedString Description
RichString GetReputationRewardText()
int GetFinalReward(Submarine sub)
Get the final reward, taking talent bonuses into account if the mission has concluded and the talents...
virtual LocalizedString SuccessMessage
readonly Location[] Locations
readonly bool ShowInMenus
Reputation(CampaignMetadata metadata, Location location, Identifier identifier, int minReputation, int maxReputation, int initialReputation)
static Color GetReputationColor(float normalizedValue)
LocalizedString GetFormattedReputationText(bool addColorTags=false)
static RichString Rich(LocalizedString str, Func< string, string >? postProcess=null)
GUIFrame CreateSummaryFrame(GameSession gameSession, string endMessage, CampaignMode.TransitionType transitionType=CampaignMode.TransitionType.None, TraitorManager.TraitorResults? traitorResults=null)
void CreateReputationInfoPanel(GUIComponent parent, CampaignMode campaignMode)
static void DrawReputationBar(SpriteBatch sb, Rectangle rect, float normalizedReputation, float minReputation, float maxReputation)
static void AddSeparators(GUIComponent container)
static void UpdateMissionStateIcon(bool success, GUIImage missionIcon, float delay=0.5f)
GUILayoutGroup ButtonArea
static GUIComponent CreateMissionEntry(GUIComponent parent, LocalizedString header, List< LocalizedString > textContent, int difficultyIconCount, Sprite icon, Color iconColor, out GUIImage missionIcon)
RoundSummary(GameMode gameMode, IEnumerable< Mission > selectedMissions, Location startLocation, Location endLocation)