3 using Microsoft.Xna.Framework;
5 using System.Collections.Generic;
6 using System.Collections.Immutable;
21 public Action<SubmarineInfo, string, string, CampaignSettings>
StartNewGame;
45 this.loadGameContainer = loadGameContainer;
51 if (
string.IsNullOrEmpty(saveInfo.FilePath))
53 DebugConsole.AddWarning(
"Error when updating campaign load menu: path to a save file was empty.\n" + Environment.StackTrace);
59 style:
"ListBoxElement")
65 new RectTransform(
new Vector2(1.0f, 0.5f), saveFrame.RectTransform),
66 Path.GetFileNameWithoutExtension(saveInfo.FilePath),
67 textColor: GUIStyle.TextColorBright)
72 if (saveInfo.EnabledContentPackageNames !=
null && saveInfo.EnabledContentPackageNames.Any())
77 saveFrame.ToolTip =
string.Join(
"\n", errorMsg, TextManager.Get(
"campaignmode.contentpackagemismatchwarning"));
86 text: saveInfo.SubmarineName,
87 font: GUIStyle.SmallFont)
90 UserData = saveInfo.FilePath
93 string saveTimeStr =
string.Empty;
94 if (saveInfo.SaveTime.TryUnwrap(out var time))
96 saveTimeStr = time.ToLocalUserString();
99 new RectTransform(
new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
101 textAlignment: Alignment.Right,
102 font: GUIStyle.SmallFont)
104 CanBeFocused =
false,
105 UserData = saveInfo.FilePath
115 if (c1.GUIComponent.UserData is not
CampaignMode.SaveInfo file1
116 || c2.GUIComponent.UserData is not
CampaignMode.SaveInfo file2)
121 if (!file1.SaveTime.TryUnwrap(out var file1WriteTime)
122 || !file2.SaveTime.TryUnwrap(out var file2WriteTime))
127 return file2WriteTime.CompareTo(file1WriteTime);
153 return new CampaignSettings(element:
null)
178 private readonly Func<T> getter;
179 private readonly Action<T> setter;
183 return getter.Invoke();
188 setter.Invoke(value);
198 private readonly
struct SettingCarouselElement<T>
201 public readonly T Value;
202 public readonly
bool IsHidden;
204 public SettingCarouselElement(T value,
string label,
bool isHidden =
false)
207 Label = TextManager.Get(label).Fallback(label);
214 const float verticalSize = 0.14f;
216 bool loadingPreset =
false;
221 childAnchor:
Anchor.CenterLeft);
224 TextManager.Get(
"campaignsettingpreset"));
227 elementCount: CampaignModePresets.List.Length + 1);
228 presetDropdown.
AddItem(TextManager.Get(
"karmapreset.custom"),
null);
233 foreach (CampaignSettings settings
in CampaignModePresets.List)
235 string name = settings.PresetName;
236 presetDropdown.AddItem(TextManager.Get($
"preset.{name}").Fallback(name), settings);
238 if (settings.PresetName.Equals(prevSettings.PresetName, StringComparison.OrdinalIgnoreCase))
240 presetDropdown.SelectItem(settings);
245 get: () => presetDropdown.SelectedData is CampaignSettings settings ? settings.PresetName :
string.Empty,
246 set:
static _ => { });
250 Spacing = GUI.IntScale(5)
261 TextManager.Get(
"CampaignOption.EnableTutorial"),
262 TextManager.Get(
"campaignoption.enabletutorial.tooltip"),
263 prevSettings.TutorialEnabled,
271 TextManager.Get(
"CampaignOption.EnableRadiation"),
272 TextManager.Get(
"campaignoption.enableradiation.tooltip"),
273 prevSettings.RadiationEnabled,
282 ImmutableArray<SettingCarouselElement<Identifier>> startingSetOptions =
284 .OrderBy(s => s.Order)
285 .Select(
set =>
new SettingCarouselElement<Identifier>(
287 $
"startitemset.{set.Identifier}"))
289 SettingCarouselElement<Identifier> prevStartingSet = startingSetOptions
290 .FirstOrNull(element => element.Value == prevSettings.StartItemSet)
291 ?? startingSetOptions[1];
294 TextManager.Get(
"startitemset"),
295 TextManager.Get(
"startitemsettooltip"),
302 ImmutableArray<SettingCarouselElement<StartingBalanceAmountOption>> fundOptions = ImmutableArray.Create(
307 SettingCarouselElement<StartingBalanceAmountOption> prevStartingFund = fundOptions
308 .FirstOrNull(element => element.Value == prevSettings.StartingBalanceAmount)
312 TextManager.Get(
"startingfundsdescription"),
313 TextManager.Get(
"startingfundstooltip"),
322 TextManager.Get(
"maxmissioncount"),
323 TextManager.Get(
"maxmissioncounttooltip"),
324 prevSettings.MaxMissionCount,
326 minValue: CampaignSettings.MinMissionCountLimit,
327 maxValue: CampaignSettings.MaxMissionCountLimit,
332 CampaignSettings.MultiplierSettings rewardMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"MissionRewardMultiplier");
335 TextManager.Get(
"campaignoption.missionrewardmultiplier"),
336 TextManager.Get(
"campaignoption.missionrewardmultiplier.tooltip"),
337 prevSettings.MissionRewardMultiplier,
338 valueStep: rewardMultiplierSettings.Step,
339 minValue: rewardMultiplierSettings.Min,
340 maxValue: rewardMultiplierSettings.Max,
345 CampaignSettings.MultiplierSettings shopPriceMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"ShopPriceMultiplier");
348 TextManager.Get(
"campaignoption.shoppricemultiplier"),
349 TextManager.Get(
"campaignoption.shoppricemultiplier.tooltip"),
350 prevSettings.ShopPriceMultiplier,
351 valueStep: shopPriceMultiplierSettings.Step,
352 minValue: shopPriceMultiplierSettings.Min,
353 maxValue: shopPriceMultiplierSettings.Max,
358 CampaignSettings.MultiplierSettings shipyardPriceMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"ShipyardPriceMultiplier");
361 TextManager.Get(
"campaignoption.shipyardpricemultiplier"),
362 TextManager.Get(
"campaignoption.shipyardpricemultiplier.tooltip"),
363 prevSettings.ShipyardPriceMultiplier,
364 valueStep: shipyardPriceMultiplierSettings.Step,
365 minValue: shipyardPriceMultiplierSettings.Min,
366 maxValue: shipyardPriceMultiplierSettings.Max,
375 ImmutableArray<SettingCarouselElement<WorldHostilityOption>> hostilityOptions = ImmutableArray.Create(
376 new SettingCarouselElement<WorldHostilityOption>(
WorldHostilityOption.Low,
"worldhostility.low"),
377 new SettingCarouselElement<WorldHostilityOption>(
WorldHostilityOption.Medium,
"worldhostility.medium"),
378 new SettingCarouselElement<WorldHostilityOption>(
WorldHostilityOption.High,
"worldhostility.high"),
379 new SettingCarouselElement<WorldHostilityOption>(
WorldHostilityOption.Hellish,
"worldhostility.hellish", isHidden:
true)
381 SettingCarouselElement<WorldHostilityOption> prevHostility = hostilityOptions
382 .FirstOrNull(element => element.Value == prevSettings.WorldHostility)
383 ?? hostilityOptions[1];
386 TextManager.Get(
"worldhostility"),
387 TextManager.Get(
"worldhostility.tooltip"),
394 CampaignSettings.MultiplierSettings crewVitalityMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"CrewVitalityMultiplier");
397 TextManager.Get(
"campaignoption.maxvitalitymultipliercrew"),
398 TextManager.Get(
"campaignoption.maxvitalitymultipliercrew.tooltip"),
399 prevSettings.CrewVitalityMultiplier,
400 valueStep: crewVitalityMultiplierSettings.Step,
401 minValue: crewVitalityMultiplierSettings.Min,
402 maxValue: crewVitalityMultiplierSettings.Max,
407 CampaignSettings.MultiplierSettings nonCrewVitalityMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"NonCrewVitalityMultiplier");
410 TextManager.Get(
"campaignoption.maxvitalitymultipliernoncrew"),
411 TextManager.Get(
"campaignoption.maxvitalitymultipliernoncrew.tooltip"),
412 prevSettings.NonCrewVitalityMultiplier,
413 valueStep: nonCrewVitalityMultiplierSettings.Step,
414 minValue: nonCrewVitalityMultiplierSettings.Min,
415 maxValue: nonCrewVitalityMultiplierSettings.Max,
420 CampaignSettings.MultiplierSettings oxygenSourceMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"OxygenMultiplier");
423 TextManager.Get(
"campaignoption.oxygensourcemultiplier"),
424 TextManager.Get(
"campaignoption.oxygensourcemultiplier.tooltip"),
425 prevSettings.OxygenMultiplier,
426 valueStep: oxygenSourceMultiplierSettings.Step,
427 minValue: oxygenSourceMultiplierSettings.Min,
428 maxValue: oxygenSourceMultiplierSettings.Max,
433 CampaignSettings.MultiplierSettings reactorFuelMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"FuelMultiplier");
436 TextManager.Get(
"campaignoption.reactorfuelmultiplier"),
437 TextManager.Get(
"campaignoption.reactorfuelmultiplier.tooltip"),
438 prevSettings.FuelMultiplier,
439 valueStep: reactorFuelMultiplierSettings.Step,
440 minValue: reactorFuelMultiplierSettings.Min,
441 maxValue: reactorFuelMultiplierSettings.Max,
446 CampaignSettings.MultiplierSettings repairFailMultiplierSettings = CampaignSettings.GetMultiplierSettings(
"RepairFailMultiplier");
449 TextManager.Get(
"campaignoption.repairfailmultiplier"),
450 TextManager.Get(
"campaignoption.repairfailmultiplier.tooltip"),
451 prevSettings.RepairFailMultiplier,
452 valueStep: repairFailMultiplierSettings.Step,
453 minValue: repairFailMultiplierSettings.Min,
454 maxValue: repairFailMultiplierSettings.Max,
458 ImmutableArray<SettingCarouselElement<PatdownProbabilityOption>> patdownProbabilityPresets = ImmutableArray.Create(
464 SettingCarouselElement<PatdownProbabilityOption> prevPatdownProbability = patdownProbabilityPresets
465 .FirstOrNull(element => element.Value == prevSettings.PatdownProbability)
466 ?? patdownProbabilityPresets[1];
469 TextManager.Get(
"campaignoption.patdownprobability"),
470 TextManager.Get(
"campaignoption.patdownprobability.tooltip"),
471 prevPatdownProbability,
473 patdownProbabilityPresets,
479 TextManager.Get(
"campaignoption.showhuskwarning"),
480 TextManager.Get(
"campaignoption.showhuskwarning.tooltip"),
481 prevSettings.ShowHuskWarning,
485 presetDropdown.OnSelected = (_, o) =>
487 if (o is not CampaignSettings settings) {
return false; }
489 loadingPreset =
true;
490 tutorialEnabled.
SetValue(isSinglePlayer && settings.TutorialEnabled);
491 radiationEnabled.
SetValue(settings.RadiationEnabled);
492 maxMissionCountInput.
SetValue(settings.MaxMissionCount);
493 startingFundsInput.
SetValue(settings.StartingBalanceAmount);
494 hostilityInput.
SetValue(settings.WorldHostility);
495 startingSetInput.
SetValue(settings.StartItemSet);
496 crewVitalityMultiplier.
SetValue(settings.CrewVitalityMultiplier);
497 nonCrewVitalityMultiplier.
SetValue(settings.NonCrewVitalityMultiplier);
498 oxygenMultiplier.
SetValue(settings.OxygenMultiplier);
499 fuelMultiplier.
SetValue(settings.FuelMultiplier);
500 rewardMultiplier.
SetValue(settings.MissionRewardMultiplier);
501 shopPriceMultiplier.
SetValue(settings.ShopPriceMultiplier);
502 shipyardPriceMultiplier.
SetValue(settings.ShipyardPriceMultiplier);
503 repairFailMultiplier.
SetValue(settings.RepairFailMultiplier);
504 patdownProbability.
SetValue(settings.PatdownProbability);
505 huskWarning.
SetValue(settings.ShowHuskWarning);
506 loadingPreset =
false;
510 void OnValuesChanged()
512 if (loadingPreset) {
return; }
513 presetDropdown.Select(0);
518 SelectedPreset = presetValue,
519 TutorialEnabled = tutorialEnabled,
520 RadiationEnabled = radiationEnabled,
521 MaxMissionCount = maxMissionCountInput,
522 StartingFunds = startingFundsInput,
523 WorldHostility = hostilityInput,
524 StartItemSet = startingSetInput,
525 CrewVitalityMultiplier = crewVitalityMultiplier,
526 NonCrewVitalityMultiplier = nonCrewVitalityMultiplier,
527 OxygenMultiplier = oxygenMultiplier,
528 FuelMultiplier = fuelMultiplier,
529 MissionRewardMultiplier = rewardMultiplier,
530 ShopPriceMultiplier = shopPriceMultiplier,
531 ShipyardPriceMultiplier = shipyardPriceMultiplier,
532 RepairFailMultiplier = repairFailMultiplier,
533 PatdownProbability = patdownProbability,
534 ShowHuskWarning = huskWarning,
554 horizontalSize: 0.55f,
555 verticalSize: verticalSize);
559 style:
"GUIMinusButton",
560 textAlignment: Alignment.Center);
564 style:
"GUIPlusButton",
565 textAlignment: Alignment.Center);
569 textAlignment: Alignment.Center,
572 customPlusMinusButtons: (plusButton, minusButton))
574 IntValue = defaultValue,
575 MinValueInt = minValue,
576 MaxValueInt = maxValue,
577 ValueStep = valueStep,
604 horizontalSize: 0.55f,
605 verticalSize: verticalSize);
609 style:
"GUIMinusButton",
610 textAlignment: Alignment.Center);
614 style:
"GUIPlusButton",
615 textAlignment: Alignment.Center);
619 textAlignment: Alignment.Center,
622 customPlusMinusButtons: (plusButton, minusButton))
624 FloatValue = defaultValue,
625 MinValueFloat = minValue,
626 MaxValueFloat = maxValue,
627 ValueStep = valueStep,
636 i => numberInput.
FloatValue = (
float)Math.Round(i, 1));
643 SettingCarouselElement<T> defaultValue,
645 ImmutableArray<SettingCarouselElement<T>> options,
652 horizontalSize: 0.55f,
653 verticalSize: verticalSize);
657 style:
"GUIButtonToggleLeft",
658 textAlignment: Alignment.Center)
668 textAlignment: Alignment.Center,
672 IntValue = options.IndexOf(defaultValue),
674 MaxValueInt = options.Length,
681 text: defaultValue.Label.Value,
682 textAlignment: Alignment.Center,
683 createPenIcon:
false)
690 style:
"GUIButtonToggleRight",
691 textAlignment: Alignment.Center)
698 bool ChangeValue(
GUIButton btn,
object userData)
700 if (userData is not
int change) {
return false; }
702 int hiddenOptions = 0;
704 for (
int i = options.Length - 1; i >= 0; i--)
706 if (options[i].IsHidden)
714 int limit = options.Length - hiddenOptions;
718 limit = options.Length;
721 int newValue = MathUtils.PositiveModulo(Math.Clamp(numberInput.
IntValue + change, min: -1, max: limit), limit);
728 void SetValue(
int value)
731 inputLabel.
Text = options[value].Label.Value;
735 () => options[numberInput.
IntValue].Value,
736 t => SetValue(options.IndexOf(e => Equals(e.Value, t)))
748 GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, 0.625f, verticalSize);
751 childAnchor:
Anchor.Center);
776 float horizontalSize,
782 childAnchor:
Anchor.CenterLeft);
786 font: parent.
Rect.Width < 320 ? GUIStyle.SmallFont : GUIStyle.Font,
794 childAnchor:
Anchor.CenterLeft)
796 RelativeSpacing = 0.05f,
801 return inputContainer;
805 public abstract void CreateLoadMenu(IEnumerable<CampaignMode.SaveInfo> saveFiles =
null);
809 if (obj is not
CampaignMode.SaveInfo saveInfo) {
return false; }
811 var header = TextManager.Get(
"deletedialoglabel");
812 var body = TextManager.GetWithVariable(
"deletedialogquestion",
"[file]", Path.GetFileNameWithoutExtension(saveInfo.FilePath));
814 EventEditorScreen.AskForConfirmation(header, body, () =>
816 SaveUtil.DeleteSave(saveInfo.FilePath);
817 prevSaveFiles?.RemoveAll(s => s.FilePath == saveInfo.FilePath);
Action< string > LoadGame
readonly GUIComponent newGameContainer
CampaignSetupUI(GUIComponent newGameContainer, GUIComponent loadGameContainer)
GUITextBlock InitialMoneyText
GUIComponent CreateSaveElement(CampaignMode.SaveInfo saveInfo)
Action< SubmarineInfo, string, string, CampaignSettings > StartNewGame
static CampaignSettingElements CreateCampaignSettingList(GUIComponent parent, CampaignSettings prevSettings, bool isSinglePlayer)
List< CampaignMode.SaveInfo > prevSaveFiles
GUIButton CampaignCustomizeButton
GUIMessageBox CampaignCustomizeSettings
abstract void CreateLoadMenu(IEnumerable< CampaignMode.SaveInfo > saveFiles=null)
bool DeleteSave(GUIButton button, object obj)
RectTransform RectTransform
GUIComponent AddItem(LocalizedString text, object userData=null, LocalizedString toolTip=null, Color? color=null, Color? textColor=null)
GUIFrame Content
A frame that contains the contents of the listbox. The frame itself is not rendered.
OnSelectedHandler OnSelected
static bool IsCompatibleWithEnabledContentPackages(IList< string > contentPackageNames, out LocalizedString errorMsg)
Defines a point in the event that GoTo actions can jump to.
static GUITextBlock CreateSubHeader(string textTag, GUIComponent parent, string toolTipTag=null)
StartingBalanceAmountOption
SettingValue< float > OxygenMultiplier
SettingValue< float > CrewVitalityMultiplier
SettingValue< float > RepairFailMultiplier
SettingValue< int > MaxMissionCount
SettingValue< float > MissionRewardMultiplier
SettingValue< bool > RadiationEnabled
SettingValue< PatdownProbabilityOption > PatdownProbability
SettingValue< Identifier > StartItemSet
SettingValue< bool > TutorialEnabled
SettingValue< float > ShipyardPriceMultiplier
SettingValue< float > NonCrewVitalityMultiplier
SettingValue< WorldHostilityOption > WorldHostility
SettingValue< StartingBalanceAmountOption > StartingFunds
readonly CampaignSettings CreateSettings()
SettingValue< string > SelectedPreset
SettingValue< bool > ShowHuskWarning
SettingValue< float > FuelMultiplier
SettingValue< float > ShopPriceMultiplier
SettingValue(Func< T > get, Action< T > set)