diff --git a/X2WOTCCommunityHighlander/Localization/X2WOTCCommunityHighlander.int b/X2WOTCCommunityHighlander/Localization/X2WOTCCommunityHighlander.int index f984ddc5a..fb8f2f9b9 100644 --- a/X2WOTCCommunityHighlander/Localization/X2WOTCCommunityHighlander.int +++ b/X2WOTCCommunityHighlander/Localization/X2WOTCCommunityHighlander.int @@ -14,6 +14,13 @@ ModIncompatiblePopupTitle="detected INCOMPATIBLE mods" ModIncompatible="Please DEACTIVATE the following mods and restart or %s will not work properly:" DisablePopup="DO NOT SHOW ME THIS AGAIN" +; Issue #909 +ModRequiresNewerHighlanderVersionTitle = "MOD REQUIRES NEWER HIGHLANDER VERSION" +ModRequiresNewerHighlanderVersionText = "Mod requires newer Highlander version:" +CurrentHighlanderVersionTitle = "Installed Version:" +RequiredHighlanderVersionTitle = "Required Version: " +ModRequiresNewerHighlanderVersionExtraText = "Please update X2WOTCCommunityHighlander to the required version. Otherwise you may experience crashes and other malfunctions." + [X2WOTCCH_UIScreenListener_ShellPopup] ErrorTitle="Mod Configuration Error" diff --git a/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_ModDependencies.uc b/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_ModDependencies.uc index ac62fc50c..9895f0bb8 100644 --- a/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_ModDependencies.uc +++ b/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_ModDependencies.uc @@ -13,6 +13,8 @@ struct ModDependencyData var name SourceName; // The stored name of the mod in case user presses "ok, please ignore" var CHPolarity Polarity; // Whether these mods are required and not installed, or incompatible but present var array Children; // The set of mods required by or incompatible with the cause + + var CHLVersionStruct RequiredHighlanderVersion; // Issue #909 }; var localized string ModRequired; @@ -21,6 +23,14 @@ var localized string ModRequiredPopupTitle; var localized string ModIncompatiblePopupTitle; var localized string DisablePopup; +// Begin Issue #909 +var localized string ModRequiresNewerHighlanderVersionTitle; +var localized string ModRequiresNewerHighlanderVersionText; +var localized string CurrentHighlanderVersionTitle; +var localized string RequiredHighlanderVersionTitle; +var localized string ModRequiresNewerHighlanderVersionExtraText; +// End Issue #909 + // Mods may install themselves as a fix mod that fixes an incompatibility // or a missing dependency (in case that mod provides functionality that // would otherwise be missing). @@ -163,6 +173,55 @@ function array GetModsWithEnabledIncompatibilities() return ModsWithIncompats; } +// Start Issue #909 +function array GetModsThatRequireNewerCHLVersion() +{ + local CHModDependency DepInfo; + local CHLVersionStruct CurrentCHLVersion; + local ModDependencyData DepData; + local array ModsThatRequireNewerCHLVersion; + + GetCurrentCHLVersion(CurrentCHLVersion); + + foreach self.DepInfos(DepInfo) + { + if (IsCurrentCHLVersionOlderThanRequired(CurrentCHLVersion, DepInfo.RequiredHighlanderVersion)) + { + DepData.ModName = DepInfo.DisplayName; + DepData.SourceName = DepInfo.Name; + DepData.RequiredHighlanderVersion = DepInfo.RequiredHighlanderVersion; + ModsThatRequireNewerCHLVersion.AddItem(DepData); + } + } + + return ModsThatRequireNewerCHLVersion; +} + +static final function GetCurrentCHLVersion(out CHLVersionStruct CurrentCHLVersion) +{ + CurrentCHLVersion.MajorVersion = class'CHXComGameVersionTemplate'.default.MajorVersion; + CurrentCHLVersion.MinorVersion = class'CHXComGameVersionTemplate'.default.MinorVersion; + CurrentCHLVersion.PatchVersion = class'CHXComGameVersionTemplate'.default.PatchVersion; +} + +static final function bool IsCurrentCHLVersionOlderThanRequired(const out CHLVersionStruct CurrentCHLVersion, const out CHLVersionStruct RequiredCHLVersion) +{ + if (CurrentCHLVersion.MajorVersion > RequiredCHLVersion.MajorVersion) + return false; + + if (CurrentCHLVersion.MajorVersion < RequiredCHLVersion.MajorVersion) + return true; + + if (CurrentCHLVersion.MinorVersion > RequiredCHLVersion.MinorVersion) + return false; + + if (CurrentCHLVersion.MinorVersion < RequiredCHLVersion.MinorVersion) + return true; + + return CurrentCHLVersion.PatchVersion < RequiredCHLVersion.PatchVersion; +} +// End Issue #909 + private function bool GetModDependencies( CHModDependency DepInfo, const out array DependencyDLCNames, diff --git a/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_UIScreenListener_ShellPopup.uc b/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_UIScreenListener_ShellPopup.uc index 58845a48b..38b93fd9d 100644 --- a/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_UIScreenListener_ShellPopup.uc +++ b/X2WOTCCommunityHighlander/Src/X2WOTCCommunityHighlander/Classes/X2WOTCCH_UIScreenListener_ShellPopup.uc @@ -9,6 +9,7 @@ class X2WOTCCH_UIScreenListener_ShellPopup var config array HideIncompatibleModWarnings; var config array HideRequiredModWarnings; +var config array HideRequiredNewerCHLVersionWarnings; // Issue #909 var X2WOTCCH_ModDependencies DependencyChecker; var config array HideGroupWarnings; @@ -29,6 +30,7 @@ event OnInit(UIScreen Screen) DependencyChecker.Init(); Screen.SetTimer(2.5f, false, nameof(IncompatibleModsPopups), self); Screen.SetTimer(2.6f, false, nameof(RequiredModsPopups), self); + Screen.SetTimer(2.65f, false, nameof(ModsRequireNewerCHLVersionPopups), self); // Issue #909 } Screen.SetTimer(2.7f, false, nameof(RunOrderPopups), self); } @@ -96,6 +98,93 @@ simulated function RequiredModsPopups() } } +// Begin Issue #909 +simulated function ModsRequireNewerCHLVersionPopups() +{ + local TDialogueBoxData kDialogData; + local array ModsNeedNewerCHL; + local ModDependencyData Mod; + local X2WOTCCH_DialogCallbackData CallbackData; + local string strCurrentVersion; + local string strRequiredVersion; + + ModsNeedNewerCHL = DependencyChecker.GetModsThatRequireNewerCHLVersion(); + strCurrentVersion = GetCurrentCHLVersionColoredText(); + + foreach ModsNeedNewerCHL(Mod) + { + if (HideRequiredNewerCHLVersionWarnings.Find(Mod.SourceName) == INDEX_NONE) + { + CallbackData = new class'X2WOTCCH_DialogCallbackData'; + CallbackData.DependencyData = Mod; + + strRequiredVersion = GetRequiredCHLVersionColoredText(Mod.RequiredHighlanderVersion); + + kDialogData.strTitle = class'X2WOTCCH_ModDependencies'.default.ModRequiresNewerHighlanderVersionTitle; + kDialogData.eType = eDialog_Warning; + kDialogData.strText = GetRequireNewerCHLVersionPopupText(Mod, strCurrentVersion, strRequiredVersion); + kDialogData.fnCallbackEx = RequireNewerCHLVersionCB; + kDialogData.strAccept = class'X2WOTCCH_ModDependencies'.default.DisablePopup; + kDialogData.strCancel = class'UIUtilities_Text'.default.m_strGenericAccept; + kDialogData.xUserData = CallbackData; + + `LOG(kDialogData.strText,, 'X2WOTCCommunityHighlander'); + + `PRESBASE.UIRaiseDialog(kDialogData); + } + } +} +static private function string GetRequireNewerCHLVersionPopupText(const out ModDependencyData Mod, string strCurrentVersion, string strRequiredVersion) +{ + local string strModDisplayName; + + strModDisplayName = Mod.ModName != "" ? Mod.ModName : string(Mod.SourceName); + + return strModDisplayName @ class'X2WOTCCH_ModDependencies'.default.ModRequiresNewerHighlanderVersionText $ "\n" $ + strCurrentVersion $ + strRequiredVersion $ "\n\n" $ + class'X2WOTCCH_ModDependencies'.default.ModRequiresNewerHighlanderVersionExtraText; +} +static private function string GetCurrentCHLVersionColoredText() +{ + local CHLVersionStruct CHLVersion; + local string strVersionText; + + class'X2WOTCCH_ModDependencies'.static.GetCurrentCHLVersion(CHLVersion); + + strVersionText = CHLVersion.MajorVersion $ "." $ CHLVersion.MinorVersion $ "." $ CHLVersion.PatchVersion; + + return class'X2WOTCCH_ModDependencies'.default.CurrentHighlanderVersionTitle @ class'UIUtilities_Text'.static.GetColoredText(strVersionText, eUIState_Bad) $ "\n"; +} +static private function string GetRequiredCHLVersionColoredText(const out CHLVersionStruct CHLVersion) +{ + local string strVersionText; + + strVersionText = CHLVersion.MajorVersion $ "." $ CHLVersion.MinorVersion $ "." $ CHLVersion.PatchVersion; + + return class'X2WOTCCH_ModDependencies'.default.RequiredHighlanderVersionTitle @ class'UIUtilities_Text'.static.GetColoredText(strVersionText, eUIState_Good); +} + +simulated function RequireNewerCHLVersionCB(Name eAction, UICallbackData xUserData) +{ + local X2WOTCCH_DialogCallbackData CallbackData; + + if (eAction == 'eUIAction_Accept') + { + CallbackData = X2WOTCCH_DialogCallbackData(xUserData); + HideRequiredNewerCHLVersionWarnings.AddItem(CallbackData.DependencyData.SourceName); + + `PRESBASE.PlayUISound(eSUISound_MenuSelect); + + self.SaveConfig(); + } + else + { + `PRESBASE.PlayUISound(eSUISound_MenuSelect); + } +} +// End Issue #909 + simulated function IncompatibleModsCB(Name eAction, UICallbackData xUserData) { local X2WOTCCH_DialogCallbackData CallbackData; diff --git a/X2WOTCCommunityHighlander/Src/XComGame/Classes/CHModDependency.uc b/X2WOTCCommunityHighlander/Src/XComGame/Classes/CHModDependency.uc index a9ab41de7..273c68b0d 100644 --- a/X2WOTCCommunityHighlander/Src/XComGame/Classes/CHModDependency.uc +++ b/X2WOTCCommunityHighlander/Src/XComGame/Classes/CHModDependency.uc @@ -128,3 +128,30 @@ var config array IgnoreIncompatibleMods; var config array RequiredMods; var config array IgnoreRequiredMods; var config string DisplayName; + +// Start Issue #909 +/// HL-Docs: feature:RequiredHighlanderVersion; issue:909; tags:compatibility +/// Mods can specify the required Highlander version in the mod's `XComGame.ini`, e.g.: +///```ini +/// [DLCName CHModDependency] +/// RequiredHighlanderVersion = (MajorVersion = 1, MinorVersion = 22, PatchVersion = 0) +///``` +/// If the mod user has an older version of the Highlander installed, they will +/// see a popup warning when they start the game. +/// Note: this feature is disabled if the game is started without the `-review` +/// launch argument. +struct CHLVersionStruct +{ + var int MajorVersion; + var int MinorVersion; + var int PatchVersion; + + structdefaultproperties + { + MajorVersion = -1 + MinorVersion = -1 + PatchVersion = -1 + } +}; +var config CHLVersionStruct RequiredHighlanderVersion; +// End Issue #909 \ No newline at end of file