Files
zzz_REBIRTH__Utils/Harmony/CustomGameOptionsHarmony.cs
2025-06-04 16:44:53 +09:30

388 lines
15 KiB
C#

using System.Globalization;
public class CustomGameOptionsHarmony
{
private const string CustomAttrGamePrefSelectorId = "CustomAttrGamePrefSelectorId";
private const string CustomAttrDefaultValue = "CustomAttrDefaultValue";
private const string CustomNamePrefix = "Custom";
public static int GamePrefValue = 500;
private const string SCoreAssemblyName = "SCore,";
private const string SCoreConfigurationClass = "Configuration";
private const string SCoreCheckFeatureStatusMethod = "CheckFeatureStatus";
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("Init")]
[HarmonyPatch(new Type[] { })]
public class PatchXUiC_GamePrefSelectorInit
{
static bool Prefix(XUiC_GamePrefSelector __instance)
{
if (__instance.ViewComponent.ID.StartsWith(CustomNamePrefix))
{
// Store the ViewComonponent.ID in temp storage for use in Postfix and other Harmony methods below
__instance.CustomAttributes.Set(CustomAttrGamePrefSelectorId, __instance.ViewComponent.ID);
// Temporarily use enum 'Last'
AccessTools.Field(typeof(XUiView), "id").SetValue(__instance.ViewComponent, "Last");
}
return true;
}
static void Postfix(XUiC_GamePrefSelector __instance,
ref EnumGamePrefs ___gamePref,
ref GamePrefs.EnumType ___valueType)
{
// If we are a Custom GameOption then get the correct ViewComponent ID from temp storage, then set the correct ViewComponent.ID and the GamePref to a new custom Enum value
var id = __instance.CustomAttributes.GetString(CustomAttrGamePrefSelectorId);
if (id.StartsWith(CustomNamePrefix))
{
GamePrefValue++;
___gamePref = (EnumGamePrefs)GamePrefValue;
AccessTools.Field(typeof(XUiView), "id").SetValue(__instance.ViewComponent, id);
// Set DefaultValue if nothing was loaded from configs
if (!CustomGameOptions.HasValue(id))
{
switch (___valueType)
{
case GamePrefs.EnumType.Int:
CustomGameOptions.SetValue(id, __instance.CustomAttributes.GetInt(CustomAttrDefaultValue));
break;
case GamePrefs.EnumType.String:
CustomGameOptions.SetValue(id, __instance.CustomAttributes.GetString(CustomAttrDefaultValue));
break;
case GamePrefs.EnumType.Bool:
CustomGameOptions.SetValue(id, __instance.CustomAttributes.GetBool(CustomAttrDefaultValue));
break;
}
}
}
}
}
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("SetVisible")]
[HarmonyPatch(new Type[] { typeof(bool) })]
public class PatchXUiC_GamePrefSelectorSetVisible
{
static bool Prefix(XUiC_GamePrefSelector __instance)
{
if (IsCustomGameOption(__instance))
{
__instance.ViewComponent.IsVisible = true;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("ControlCombo_OnValueChanged")]
[HarmonyPatch(new Type[] { typeof(XUiController), typeof(XUiC_GamePrefSelector.GameOptionValue), typeof(XUiC_GamePrefSelector.GameOptionValue) })]
public class PatchXUiC_GamePrefSelectorControlCombo_OnValueChanged
{
static bool Prefix(XUiC_GamePrefSelector __instance,
XUiC_GamePrefSelector.GameOptionValue _newValue,
ref GamePrefs.EnumType ___valueType)
{
if (IsCustomGameOption(__instance))
{
var id = __instance.CustomAttributes.GetString(CustomAttrGamePrefSelectorId);
//Log.Out("CustomGameOptionsHarmony-ControlCombo_OnValueChanged id: " + id);
//Log.Out("CustomGameOptionsHarmony-ControlCombo_OnValueChanged _newValue: " + _newValue);
switch (___valueType)
{
case GamePrefs.EnumType.Int:
CustomGameOptions.SetValue(id, _newValue.IntValue);
break;
case GamePrefs.EnumType.String:
//Log.Out("CustomGameOptionsHarmony-ControlCombo_OnValueChanged _newValue.StringValue: " + _newValue.StringValue);
//Log.Out("CustomGameOptionsHarmony-ControlCombo_OnValueChanged LOCALIZED _newValue.StringValue: " + Localization.Get(_newValue.StringValue));
CustomGameOptions.SetValue(id, _newValue.StringValue);
if (id == "CustomScenario" && _newValue.StringValue == "purge")
{
}
break;
case GamePrefs.EnumType.Bool:
CustomGameOptions.SetValue(id, _newValue.IntValue == 1);
break;
}
AccessTools.Method(typeof(XUiC_GamePrefSelector), "CheckDefaultValue").Invoke(__instance, new object[] { });
return false;
}
return true;
}
}
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("ControlText_OnChangeHandler")]
[HarmonyPatch(new Type[] { typeof(XUiController), typeof(string), typeof(bool) })]
public class PatchXUiC_GamePrefSelectorControlText_OnChangeHandler
{
static bool Prefix(XUiC_GamePrefSelector __instance,
string _text,
ref GamePrefs.EnumType ___valueType)
{
if (IsCustomGameOption(__instance))
{
var id = __instance.CustomAttributes.GetString(CustomAttrGamePrefSelectorId);
switch (___valueType)
{
case GamePrefs.EnumType.Int:
{
if (int.TryParse(_text, out int value))
{
CustomGameOptions.SetValue(id, value);
}
break;
}
case GamePrefs.EnumType.String:
CustomGameOptions.SetValue(id, _text);
break;
}
AccessTools.Method(typeof(XUiC_GamePrefSelector), "CheckDefaultValue").Invoke(__instance, new object[] { });
return false;
}
return true;
}
}
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("SetCurrentValue")]
[HarmonyPatch(new Type[] { })]
public class PatchXUiC_GamePrefSelectorSetCurrentValue
{
static bool Prefix(XUiC_GamePrefSelector __instance,
ref string[] ___valuesFromXml,
ref GamePrefs.EnumType ___valueType,
ref bool ___isTextInput,
ref XUiC_ComboBoxList<XUiC_GamePrefSelector.GameOptionValue> ___controlCombo,
ref XUiC_TextInput ___controlText,
string ___valueLocalizationPrefixFromXml)
{
if (IsCustomGameOption(__instance))
{
var id = __instance.CustomAttributes.GetString(CustomAttrGamePrefSelectorId);
switch (___valueType)
{
case GamePrefs.EnumType.Int:
{
/*if (!string.IsNullOrEmpty(___valueLocalizationPrefixFromXml))
{
Log.Out("PatchXUiC_GamePrefSelectorSetCurrentValue-SetCurrentValue ___valueLocalizationPrefixFromXml: " + ___valueLocalizationPrefixFromXml);
}*/
if (___isTextInput)
{
___controlText.Text = CustomGameOptions.GetInt(id).ToString();
break;
}
for (int i = 1; i < ___controlCombo.Elements.Count; i++)
{
if (___controlCombo.Elements[i].IntValue == CustomGameOptions.GetInt(id))
{
___controlCombo.SelectedIndex = i;
break;
}
}
break;
}
case GamePrefs.EnumType.String:
{
if (___isTextInput)
{
___controlText.Text = CustomGameOptions.GetString(id);
break;
}
for (int i = 1; i < ___controlCombo.Elements.Count; i++)
{
if (___controlCombo.Elements[i].StringValue == CustomGameOptions.GetString(id))
{
___controlCombo.SelectedIndex = i;
break;
}
}
break;
}
case GamePrefs.EnumType.Bool:
___controlCombo.SelectedIndex = CustomGameOptions.GetBool(id) ? 1 : 0;
break;
}
AccessTools.Method(typeof(XUiC_GamePrefSelector), "CheckDefaultValue").Invoke(__instance, new object[] { });
return false;
}
return true;
}
}
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("IsDefaultValueForGameMode")]
[HarmonyPatch(new Type[] { })]
public class PatchXUiC_GamePrefSelectorIsDefaultValueForGameMode
{
static bool Prefix(XUiC_GamePrefSelector __instance,
ref bool __result,
ref GamePrefs.EnumType ___valueType,
ref XUiC_ComboBoxList<XUiC_GamePrefSelector.GameOptionValue> ___controlCombo,
ref XUiC_TextInput ___controlText,
ref bool ___isTextInput)
{
if (IsCustomGameOption(__instance))
{
switch (___valueType)
{
case GamePrefs.EnumType.Int:
{
int intValue;
if (___isTextInput)
{
StringParsers.TryParseSInt32(___controlText.Text, out intValue, 0, -1, NumberStyles.Integer);
}
else
{
intValue = ___controlCombo.Value.IntValue;
}
__result = intValue == __instance.CustomAttributes.GetInt(CustomAttrDefaultValue);
break;
}
case GamePrefs.EnumType.String:
{
if (___isTextInput)
{
__result = ___controlText.Text == __instance.CustomAttributes.GetString(CustomAttrDefaultValue);
break;
}
__result = ___controlCombo.Value.StringValue == __instance.CustomAttributes.GetString(CustomAttrDefaultValue);
break;
}
case GamePrefs.EnumType.Bool:
__result = ___controlCombo.Value.IntValue == 1 == __instance.CustomAttributes.GetBool(CustomAttrDefaultValue);
break;
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(XUiC_NewContinueGame))]
[HarmonyPatch("SaveGameOptions")]
[HarmonyPatch(new Type[] { })]
public class PatchXUiC_NewContinueGameSaveGameOptions
{
static void Postfix(XUiC_NewContinueGame __instance)
{
Log.Out("SaveGameOptions");
CustomGameOptions.SaveGameOptions();
}
}
[HarmonyPatch(typeof(XUiC_GamePrefSelector))]
[HarmonyPatch("ParseAttribute")]
[HarmonyPatch(new Type[] { typeof(string), typeof(string), typeof(XUiController) })]
public class PatchXUiC_GamePrefSelectorParseAttribute
{
static bool Prefix(XUiC_GamePrefSelector __instance,
ref string _name,
ref string _value,
ref XUiController _parent,
ref GamePrefs.EnumType ___valueType)
{
// Load default values from windows.xml and save in CustomAttributes
if (_name == "default_value"
&& _value != "default_value")
{
__instance.CustomAttributes.Set(CustomAttrDefaultValue, _value);
return false;
}
return true;
}
}
private static bool IsCustomGameOption(XUiC_GamePrefSelector __instance)
{
var id = __instance.CustomAttributes.GetString(CustomAttrGamePrefSelectorId);
return !string.IsNullOrEmpty(id) && id.StartsWith(CustomNamePrefix);
}
[HarmonyPatch()]
public class PatchScoreConfigurationCheckFeatureStatus
{
[HarmonyPrepare]
public static bool Prepare(MethodBase original)
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (assembly?.FullName.StartsWith(SCoreAssemblyName) != true) continue;
foreach (Type type in assembly.GetTypes())
{
if (type.FullName != SCoreConfigurationClass) continue;
return type.GetMethod(SCoreCheckFeatureStatusMethod, new Type[] { typeof(string), typeof(string) }) != null;
}
}
return false;
}
[HarmonyTargetMethod]
static MethodBase TargetMethod()
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (assembly?.FullName.StartsWith(SCoreAssemblyName) != true) continue;
foreach (Type type in assembly.GetTypes())
{
if (type?.FullName != SCoreConfigurationClass) continue;
return type.GetMethod(SCoreCheckFeatureStatusMethod, new Type[] { typeof(string), typeof(string) });
}
}
return null;
}
static bool Prefix(ref bool __result, string strClass, string strFeature)
{
var variableName = $"{CustomNamePrefix}{strClass}{strFeature}";
if (CustomGameOptions.HasValue(variableName))
{
__result = CustomGameOptions.GetBool(variableName);
return false;
}
return true;
}
}
}