using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("DSPNormalModeVegetation")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.3.0")]
[assembly: AssemblyInformationalVersion("1.4.3")]
[assembly: AssemblyProduct("DSPNormalModeVegetation")]
[assembly: AssemblyTitle("DSPNormalModeVegetation")]
[assembly: AssemblyVersion("1.4.3.0")]
namespace DSPNormalModeVegetation;
[BepInPlugin("Zincon.DSPNormalModeVegetation", "Icarus Gardening", "1.4.3")]
[BepInProcess("DSPGAME.exe")]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "Zincon.DSPNormalModeVegetation";
public const string PluginName = "Icarus Gardening";
public const string PluginVersion = "1.4.3";
private Harmony harmony;
internal static ManualLogSource Log { get; private set; }
private void Awake()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
try
{
VegetationModePatches.ValidateTargets();
harmony = new Harmony("Zincon.DSPNormalModeVegetation");
harmony.PatchAll(typeof(VegetationModePatches));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Icarus Gardening 1.4.3 loaded. Native vegetation placement, removal, and scaling are available in regular games.");
}
catch (Exception ex)
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
harmony = null;
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to enable normal-mode vegetation placement. No sandbox or abnormality flags were changed.\n" + ex));
}
}
private void OnDestroy()
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
harmony = null;
Log = null;
}
}
internal static class VegetationCategoryCatalog
{
internal const int FirstCategory = 1;
internal const int LastCategory = 6;
internal const int NativeVegetationCategory = 3;
internal const int NativeRemovalCategory = 10;
private const int LocalCategory = 1;
private const int OrganicCategory = 2;
private const int TerrestrialCategory = 3;
private const int UninhabitableCategory = 4;
private const int OtherCategory = 5;
internal const int GalacticScaleCategory = 6;
private const int LastVanillaThemeId = 25;
private static readonly int[] BundledGalacticScaleVegetationIds = new int[34]
{
25, 26, 32, 36, 37, 39, 41, 42, 43, 45,
46, 47, 101, 102, 103, 104, 106, 121, 124, 125,
126, 601, 602, 603, 604, 605, 1001, 1002, 1003, 1004,
1005, 1006, 1007, 1023
};
private static readonly Dictionary<int, int> VanillaThemeCategoriesById = CreateVanillaThemeCategoriesById();
private static readonly Dictionary<string, int> VanillaThemeCategoriesByName = CreateVanillaThemeCategoriesByName();
private static readonly HashSet<string> VanillaGalacticScaleThemeNames = CreateVanillaGalacticScaleThemeNames();
private static readonly HashSet<string> KnownCustomGalacticScaleThemeNames = CreateKnownCustomGalacticScaleThemeNames();
private static Dictionary<int, HashSet<int>> categoryVegetationIds;
private static string lastClassificationDiagnostic;
internal static bool IsCustomCategory(int category)
{
if (category >= 1)
{
return category <= 6;
}
return false;
}
internal static string GetTitle(int category)
{
bool isZHCN = Localization.isZHCN;
switch (category)
{
case 1:
if (!isZHCN)
{
return "Local Vegetation";
}
return "本地植被";
case 2:
if (!isZHCN)
{
return "Organic Planet Vegetation";
}
return "有机行星植被";
case 3:
if (!isZHCN)
{
return "Terrestrial Planets";
}
return "类地行星";
case 4:
if (!isZHCN)
{
return "Uninhabitable";
}
return "不适宜生存";
case 5:
if (!isZHCN)
{
return "Other";
}
return "其它";
case 6:
return "GalacticScale";
default:
return string.Empty;
}
}
internal static void Rebuild()
{
categoryVegetationIds = new Dictionary<int, HashSet<int>>();
for (int i = 1; i <= 6; i++)
{
categoryVegetationIds.Add(i, new HashSet<int>());
}
AddBundledGalacticScaleVegetation(categoryVegetationIds[6]);
PlanetData localPlanet = GameMain.localPlanet;
if (localPlanet != null && (Object)(object)LDB.themes != (Object)null)
{
AddThemeVegetation(((ProtoSet<ThemeProto>)(object)LDB.themes).Select(localPlanet.theme), categoryVegetationIds[1]);
}
HashSet<int> hashSet = new HashSet<int>();
HashSet<string> hashSet2 = new HashSet<string>(KnownCustomGalacticScaleThemeNames, StringComparer.OrdinalIgnoreCase);
HashSet<string> vanillaVegetationSignatures = CollectVanillaVegetationSignatures();
int num = CollectDspAddPlanetThemeIds(hashSet);
int num2 = CollectGalacticScaleLibrary(hashSet, hashSet2, categoryVegetationIds[6], vanillaVegetationSignatures);
int[] array = new int[7];
int num3 = 0;
List<string> list = new List<string>();
if ((Object)(object)LDB.themes != (Object)null && ((ProtoSet<ThemeProto>)(object)LDB.themes).dataArray != null)
{
ThemeProto[] dataArray = ((ProtoSet<ThemeProto>)(object)LDB.themes).dataArray;
foreach (ThemeProto val in dataArray)
{
if (val == null)
{
continue;
}
bool flag = hashSet.Contains(((Proto)val).ID) || ContainsThemeName(hashSet2, ((Proto)val).Name) || ContainsThemeName(hashSet2, ((Proto)val).name);
int num4 = (flag ? 6 : GetThemeCategory(val));
bool flag2 = !flag || IsCustomVegetationSet(GetThemeVegetationIds(val), vanillaVegetationSignatures);
if (flag2)
{
AddThemeVegetation(val, categoryVegetationIds[num4]);
if (flag)
{
num3++;
}
}
array[num4]++;
list.Add($"{((Proto)val).ID}:{GetThemeDiagnosticName(val)}" + "->" + GetDiagnosticCategoryName(num4) + $"[{CountThemeVegetation(val)}]" + ((!flag) ? string.Empty : (flag2 ? "(GS-custom)" : "(GS-clone)")));
}
}
string text = string.Join("; ", list.ToArray());
if (!string.Equals(text, lastClassificationDiagnostic, StringComparison.Ordinal))
{
lastClassificationDiagnostic = text;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("Vegetation theme classification: " + text));
}
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("Vegetation categories rebuilt from vanilla theme IDs and external registries: " + $"bundled-gs-vegetation={BundledGalacticScaleVegetationIds.Length}, " + $"vanilla-organic-themes={array[2]}, " + $"vanilla-terrestrial-themes={array[3]}, " + $"vanilla-uninhabitable-themes={array[4]}, " + $"other-themes={array[5]}, " + $"gs-themes={array[6]}, " + $"gs-custom-vegetation-themes={num3}, " + $"dspaddplanet-registry={num}, " + $"gs-library={num2}; " + $"local={categoryVegetationIds[1].Count}, " + $"organic={categoryVegetationIds[2].Count}, " + $"terrestrial={categoryVegetationIds[3].Count}, " + $"uninhabitable={categoryVegetationIds[4].Count}, " + $"other={categoryVegetationIds[5].Count}, " + $"galactic-scale={categoryVegetationIds[6].Count}."));
}
}
private static void AddBundledGalacticScaleVegetation(HashSet<int> vegetationIds)
{
int[] bundledGalacticScaleVegetationIds = BundledGalacticScaleVegetationIds;
foreach (int item in bundledGalacticScaleVegetationIds)
{
vegetationIds.Add(item);
}
}
internal static HashSet<int> CollectVegetationIds(int category)
{
if (categoryVegetationIds == null)
{
Rebuild();
}
if (!categoryVegetationIds.TryGetValue(category, out var value))
{
return new HashSet<int>();
}
return value;
}
private static int GetThemeCategory(ThemeProto theme)
{
if (theme == null)
{
return 5;
}
if (VanillaThemeCategoriesById.TryGetValue(((Proto)theme).ID, out var value) || TryGetVanillaThemeCategory(((Proto)theme).Name, out value) || TryGetVanillaThemeCategory(((Proto)theme).name, out value))
{
return value;
}
if (ContainsThemeName(KnownCustomGalacticScaleThemeNames, ((Proto)theme).Name) || ContainsThemeName(KnownCustomGalacticScaleThemeNames, ((Proto)theme).name))
{
return 6;
}
return 5;
}
private static bool TryGetVanillaThemeCategory(string themeName, out int category)
{
if (!string.IsNullOrWhiteSpace(themeName) && VanillaThemeCategoriesByName.TryGetValue(themeName.Trim(), out category))
{
return true;
}
category = 5;
return false;
}
private static Dictionary<int, int> CreateVanillaThemeCategoriesById()
{
return new Dictionary<int, int>
{
[1] = 2,
[2] = 5,
[3] = 5,
[4] = 5,
[5] = 5,
[6] = 3,
[7] = 4,
[8] = 2,
[9] = 4,
[10] = 4,
[11] = 3,
[12] = 3,
[13] = 4,
[14] = 2,
[15] = 2,
[16] = 2,
[17] = 4,
[18] = 2,
[19] = 3,
[20] = 4,
[21] = 5,
[22] = 2,
[23] = 3,
[24] = 4,
[25] = 2
};
}
private static Dictionary<string, int> CreateVanillaThemeCategoriesByName()
{
Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
AddThemes(dictionary, 2, "Ocean 1", "Ocean 2", "Ocean 3", "Ocean 4", "Ocean 5", "Ocean 6", "Desert 8", "Desert 11");
AddThemes(dictionary, 3, "Desert 1", "Desert 3", "Desert 4", "Desert 6", "Desert 9");
AddThemes(dictionary, 4, "Lava 1", "Volcanic 1", "Desert 5");
AddThemes(dictionary, 4, "Desert 2", "Ice 1", "Desert 7", "Desert 10");
AddThemes(dictionary, 5, "Gas 1", "Gas 2", "Gas 3", "Gas 4", "Gas 5");
return dictionary;
}
private static HashSet<string> CreateVanillaGalacticScaleThemeNames()
{
return new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Mediterranean", "GasGiant", "GasGiant2", "IceGiant", "IceGiant2", "AridDesert", "AshenGelisol", "OceanicJungle", "Lava", "IceGelisol",
"Barren", "Gobi", "VolcanicAsh", "RedStone", "Prairie", "OceanWorld", "IceLake", "Hurricane", "SaltLake", "Sakura",
"GasGiant3", "GasGiant4", "IceGiant3", "IceGiant4", "GasGiant5", "AridDesert2", "IceGelisol2", "IceGelisol3", "Savanna", "CrystalDesert",
"FrozenTundra", "PandoraSwamp", "PandoraSwamp2"
};
}
private static HashSet<string> CreateKnownCustomGalacticScaleThemeNames()
{
return new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"AridDesertsmol", "AridDesert2smol", "AshenGelisolsmol", "Barrensmol", "BarrenSatellite", "Beach", "BeachCold", "Center", "Comet", "Comet11",
"Comet12", "Comet13", "Comet14", "CrystalDesertsmol", "DwarfPlanet", "FrozenTundrasmol", "GiganticForest", "GiganticForestCold", "Gobismol", "HotObsidian",
"Hurricanesmol", "IceGelisolsmol", "IceGelisol2smol", "IceGelisol3smol", "IceLakesmol", "IceMalusol", "IceMalusmol", "Inferno", "Lavasmol", "MoltenWorld",
"Obsidian", "OilGiant", "Pandora", "PandoraCold", "RedForest", "RedForestCold", "RemovedSmallPlanetTheme34", "RemovedSmallPlanetTheme35", "RemovedSmallPlanetTheme36", "SaltLakesmol",
"SulfurSea", "VolcanicAshsmol", "AcidGreenhouse"
};
}
private static void AddThemes(Dictionary<string, int> categories, int category, params string[] themeNames)
{
foreach (string key in themeNames)
{
categories.Add(key, category);
}
}
private static int CollectDspAddPlanetThemeIds(HashSet<int> themeIds)
{
try
{
if (!((FindLoadedType("DSPAddPlanet.GalacticScaleThemeRegistry")?.GetProperty("ThemeNameToId", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null, null) is IEnumerable enumerable))
{
return 0;
}
foreach (object item in enumerable)
{
if (TryReadIntMember(item, "Value", out var value) && value > 0)
{
themeIds.Add(value);
}
}
return themeIds.Count;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Could not read DspAddplanet's GalacticScale theme registry: " + ex.Message));
}
return 0;
}
}
private static int CollectGalacticScaleLibrary(HashSet<int> customThemeIds, HashSet<string> customThemeNames, HashSet<int> vegetationIds, HashSet<string> vanillaVegetationSignatures)
{
try
{
if (!((FindLoadedType("GalacticScale.GSSettings")?.GetProperty("ThemeLibrary", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null, null) is IEnumerable enumerable))
{
return 0;
}
int num = 0;
foreach (object item in enumerable)
{
object obj = ReadMember(item, "Key");
object obj2 = ReadMember(item, "Value");
if (obj2 == null)
{
continue;
}
num++;
string text = obj as string;
string text2 = ReadMember(obj2, "Name") as string;
if ((!string.IsNullOrWhiteSpace(text) && !VanillaGalacticScaleThemeNames.Contains(text)) || (!string.IsNullOrWhiteSpace(text2) && !VanillaGalacticScaleThemeNames.Contains(text2)))
{
HashSet<int> hashSet = new HashSet<int>();
AddReflectedThemeVegetation(obj2, hashSet);
if (IsCustomVegetationSet(hashSet, vanillaVegetationSignatures))
{
vegetationIds.UnionWith(hashSet);
}
AddThemeName(customThemeNames, text);
AddThemeName(customThemeNames, text2);
if (TryReadIntMember(obj2, "LDBThemeId", out var value) && value > 25)
{
customThemeIds.Add(value);
}
}
}
return num;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("Could not read GalacticScale's theme library: " + ex.Message));
}
return 0;
}
}
private static Type FindLoadedType(string fullName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type type = assemblies[i].GetType(fullName, throwOnError: false);
if (type != null)
{
return type;
}
}
return null;
}
private static object ReadMember(object instance, string memberName)
{
if (instance == null)
{
return null;
}
Type type = instance.GetType();
PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null)
{
return property.GetValue(instance, null);
}
return type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance);
}
private static bool TryReadIntMember(object instance, string memberName, out int value)
{
if (ReadMember(instance, memberName) is int num)
{
value = num;
return true;
}
value = 0;
return false;
}
private static void AddReflectedThemeVegetation(object theme, HashSet<int> vegetationIds)
{
for (int i = 0; i < 6; i++)
{
if (!(ReadMember(theme, "Vegetables" + i) is IEnumerable enumerable))
{
continue;
}
foreach (object item in enumerable)
{
if (item is int num && num > 0)
{
vegetationIds.Add(num);
}
}
}
}
private static void AddThemeName(HashSet<string> names, string name)
{
if (!string.IsNullOrWhiteSpace(name))
{
names.Add(name.Trim());
}
}
private static bool ContainsThemeName(HashSet<string> names, string name)
{
if (!string.IsNullOrWhiteSpace(name))
{
return names.Contains(name.Trim());
}
return false;
}
private static string GetThemeDiagnosticName(ThemeProto theme)
{
string text = ((!string.IsNullOrWhiteSpace(((Proto)theme).Name)) ? ((Proto)theme).Name : ((Proto)theme).name);
string text2 = ((!string.IsNullOrWhiteSpace(theme.displayName)) ? theme.displayName : theme.DisplayName);
if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text, text2, StringComparison.Ordinal))
{
return (text ?? "<unnamed>") + "/" + text2;
}
return text ?? "<unnamed>";
}
private static string GetDiagnosticCategoryName(int category)
{
return category switch
{
2 => "organic",
3 => "terrestrial",
4 => "uninhabitable",
6 => "galactic-scale",
_ => "other",
};
}
private static int CountThemeVegetation(ThemeProto theme)
{
return GetThemeVegetationIds(theme).Count;
}
private static HashSet<string> CollectVanillaVegetationSignatures()
{
HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
if (((ProtoSet<ThemeProto>)(object)LDB.themes)?.dataArray == null)
{
return hashSet;
}
ThemeProto[] dataArray = ((ProtoSet<ThemeProto>)(object)LDB.themes).dataArray;
foreach (ThemeProto val in dataArray)
{
if (val != null && VanillaThemeCategoriesById.ContainsKey(((Proto)val).ID))
{
hashSet.Add(GetVegetationSignature(GetThemeVegetationIds(val)));
}
}
return hashSet;
}
private static bool IsCustomVegetationSet(HashSet<int> vegetationIds, HashSet<string> vanillaVegetationSignatures)
{
if (vegetationIds.Count > 0)
{
return !vanillaVegetationSignatures.Contains(GetVegetationSignature(vegetationIds));
}
return false;
}
private static string GetVegetationSignature(HashSet<int> vegetationIds)
{
int[] array = new int[vegetationIds.Count];
vegetationIds.CopyTo(array);
Array.Sort(array);
return string.Join(",", array);
}
private static HashSet<int> GetThemeVegetationIds(ThemeProto theme)
{
HashSet<int> hashSet = new HashSet<int>();
AddThemeVegetation(theme, hashSet);
return hashSet;
}
private static void AddThemeVegetation(ThemeProto theme, HashSet<int> vegetationIds)
{
if (theme != null)
{
AddVegetationArray(theme.Vegetables0, vegetationIds);
AddVegetationArray(theme.Vegetables1, vegetationIds);
AddVegetationArray(theme.Vegetables2, vegetationIds);
AddVegetationArray(theme.Vegetables3, vegetationIds);
AddVegetationArray(theme.Vegetables4, vegetationIds);
AddVegetationArray(theme.Vegetables5, vegetationIds);
}
}
private static void AddVegetationArray(int[] source, HashSet<int> vegetationIds)
{
if (source == null)
{
return;
}
foreach (int num in source)
{
if (num > 0)
{
vegetationIds.Add(num);
}
}
}
}
internal static class VegetationCategoryUi
{
private static UISandboxMenu snapshotMenu;
private static bool[] originalButtonActive;
private static Sprite[] originalIcons;
private static TipSettings[] originalTips;
private static Text heading;
private static string originalHeadingText;
internal static bool TryApplyRegularChrome(UISandboxMenu menu, int selectedCategory, out string error)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
if (!TryCapture(menu, out error))
{
return false;
}
HashSet<int> hashSet = new HashSet<int>();
for (int i = 1; i < menu.categoryButtons.Length; i++)
{
UIButton val = menu.categoryButtons[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
bool flag = VegetationCategoryCatalog.IsCustomCategory(i);
bool flag2 = i == 10;
((Component)val).gameObject.SetActive(flag || flag2);
val.highlighted = (flag2 ? (menu.currentCategory == 10) : (flag && menu.currentCategory == 3 && selectedCategory == i));
if (flag)
{
TipSettings tips = val.tips;
tips.tipTitle = VegetationCategoryCatalog.GetTitle(i);
tips.tipText = string.Empty;
val.tips = tips;
int representativeId;
Sprite val2 = FindRepresentativeSprite(VegetationCategoryCatalog.CollectVegetationIds(i), hashSet, out representativeId);
if ((Object)(object)val2 != (Object)null)
{
hashSet.Add(representativeId);
}
menu.categoryIcons[i].sprite = val2 ?? originalIcons[i];
}
}
heading.text = VegetationCategoryCatalog.GetTitle((!VegetationCategoryCatalog.IsCustomCategory(selectedCategory)) ? 1 : selectedCategory);
return true;
}
internal static void RestoreNativeChrome(UISandboxMenu menu)
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
if (snapshotMenu != menu || originalButtonActive == null || originalIcons == null || originalTips == null)
{
return;
}
int num = Math.Min(menu.categoryButtons.Length, originalButtonActive.Length);
for (int i = 1; i < num; i++)
{
UIButton val = menu.categoryButtons[i];
if (!((Object)(object)val == (Object)null))
{
((Component)val).gameObject.SetActive(originalButtonActive[i]);
val.tips = originalTips[i];
if (i < menu.categoryIcons.Length && (Object)(object)menu.categoryIcons[i] != (Object)null)
{
menu.categoryIcons[i].sprite = originalIcons[i];
}
}
}
if ((Object)(object)heading != (Object)null)
{
heading.text = originalHeadingText;
}
}
internal static void HideCategoryButtons(UISandboxMenu menu)
{
if (menu?.categoryButtons == null)
{
return;
}
for (int i = 1; i < menu.categoryButtons.Length; i++)
{
UIButton val = menu.categoryButtons[i];
if ((Object)(object)val != (Object)null)
{
((Component)val).gameObject.SetActive(false);
}
}
}
internal static bool TrySetVegetationLayout(UISandboxMenu menu, Dictionary<int, UIButton> vegetationButtons, UIButton vegetationButtonPrefab, int selectedCategory, out string error)
{
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
if (!TryCapture(menu, out error))
{
return false;
}
if (vegetationButtons == null || menu.localVegeButtons == null || menu.otherVegeButtons == null || (Object)(object)menu.localVegeGroup == (Object)null || (Object)(object)menu.otherVegeGroup == (Object)null || (Object)(object)menu.vegeScrollViewConent == (Object)null)
{
error = "UISandboxMenu vegetation button storage or layout groups were not found.";
return false;
}
if (!VegetationCategoryCatalog.IsCustomCategory(selectedCategory))
{
error = $"Unexpected vegetation category {selectedCategory}.";
return false;
}
if (!EnsureBundledVegetationButtons(menu, vegetationButtons, vegetationButtonPrefab, out error))
{
return false;
}
HashSet<int> hashSet = VegetationCategoryCatalog.CollectVegetationIds(selectedCategory);
List<int> orderedButtonIds = GetOrderedButtonIds(vegetationButtons);
menu.localVegeButtons.Clear();
menu.otherVegeButtons.Clear();
((Component)menu.localVegeGroup).gameObject.SetActive(true);
HideUnselectedVegetationGroup(menu);
foreach (int item in orderedButtonIds)
{
UIButton val = vegetationButtons[item];
if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent<RectTransform>() == (Object)null)
{
error = $"Vegetation button {item} is incomplete.";
return false;
}
if (hashSet.Contains(item))
{
PlaceButton(val, menu.localVegeGroup, menu.localVegeButtons);
}
else
{
PlaceButton(val, menu.otherVegeGroup, menu.otherVegeButtons);
}
}
menu.localVegeGroup.sizeDelta = new Vector2(menu.localVegeGroup.sizeDelta.x, (float)((menu.localVegeButtons.Count / 12 + 1) * 50 + 40));
menu.otherVegeGroup.sizeDelta = new Vector2(menu.otherVegeGroup.sizeDelta.x, (float)((menu.otherVegeButtons.Count / 12 + 1) * 50 + 40));
menu.vegeScrollViewConent.anchoredPosition = new Vector2(menu.vegeScrollViewConent.anchoredPosition.x, 0f);
heading.text = VegetationCategoryCatalog.GetTitle(selectedCategory);
error = null;
return true;
}
private static bool EnsureBundledVegetationButtons(UISandboxMenu menu, Dictionary<int, UIButton> vegetationButtons, UIButton vegetationButtonPrefab, out string error)
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Invalid comparison between Unknown and I4
if ((Object)(object)vegetationButtonPrefab == (Object)null)
{
error = "The native vegetation button prefab was not found.";
return false;
}
foreach (int item in VegetationCategoryCatalog.CollectVegetationIds(6))
{
if (vegetationButtons.ContainsKey(item))
{
continue;
}
VegeProto val = ((ProtoSet<VegeProto>)(object)LDB.veges)?.Select(item);
if (val == null || (Object)(object)val.iconSprite == (Object)null || (int)val.Type == 8)
{
continue;
}
UIButton val2 = Object.Instantiate<UIButton>(vegetationButtonPrefab, (Transform)(object)menu.otherVegeGroup);
if ((Object)(object)val2 == (Object)null || ((Component)val2).transform.childCount == 0 || (Object)(object)((Component)((Component)val2).transform.GetChild(0)).GetComponent<Image>() == (Object)null)
{
if ((Object)(object)val2 != (Object)null)
{
Object.Destroy((Object)(object)((Component)val2).gameObject);
}
error = $"Could not create the native vegetation button for {item}.";
return false;
}
((Component)((Component)val2).transform.GetChild(0)).GetComponent<Image>().sprite = val.iconSprite;
val2.data = ((Proto)val).ID;
((Component)val2).gameObject.SetActive(true);
val2.onClick += menu.OnChildButtonClick;
vegetationButtons.Add(((Proto)val).ID, val2);
}
error = null;
return true;
}
internal static void HideUnselectedVegetationGroup(UISandboxMenu menu)
{
if ((Object)(object)menu?.otherVegeGroup != (Object)null)
{
((Component)menu.otherVegeGroup).gameObject.SetActive(false);
}
}
internal static void UpdateScaleDisplay(int selectedCategory, bool hasSelectedVegetation, float scale)
{
if (!((Object)(object)heading == (Object)null) && VegetationCategoryCatalog.IsCustomCategory(selectedCategory))
{
string title = VegetationCategoryCatalog.GetTitle(selectedCategory);
heading.text = (hasSelectedVegetation ? (title + (Localization.isZHCN ? " | 倍率 " : " | Scale ") + scale.ToString("0.00") + "x") : title);
}
}
private static bool TryCapture(UISandboxMenu menu, out string error)
{
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)menu == (Object)null || menu.categoryButtons == null || menu.categoryButtons.Length <= 6 || menu.categoryIcons == null || menu.categoryIcons.Length <= 6 || menu.categoryTips == null || menu.categoryTips.Length <= 6 || (Object)(object)menu.localVegeGroup == (Object)null)
{
error = "UISandboxMenu category slots 1-6 or the vegetation group were not found.";
return false;
}
for (int i = 1; i <= 6; i++)
{
if ((Object)(object)menu.categoryButtons[i] == (Object)null || (Object)(object)menu.categoryIcons[i] == (Object)null || (Object)(object)menu.categoryTips[i] == (Object)null)
{
error = $"UISandboxMenu category slot {i} is incomplete.";
return false;
}
}
if (snapshotMenu == menu && originalButtonActive != null && (Object)(object)heading != (Object)null)
{
error = null;
return true;
}
Text val = FindHeading(menu.localVegeGroup);
if ((Object)(object)val == (Object)null)
{
error = "The native local-vegetation heading was not found.";
return false;
}
snapshotMenu = menu;
originalButtonActive = new bool[menu.categoryButtons.Length];
originalIcons = (Sprite[])(object)new Sprite[menu.categoryButtons.Length];
originalTips = (TipSettings[])(object)new TipSettings[menu.categoryButtons.Length];
for (int j = 0; j < menu.categoryButtons.Length; j++)
{
UIButton val2 = menu.categoryButtons[j];
if ((Object)(object)val2 != (Object)null)
{
originalButtonActive[j] = ((Component)val2).gameObject.activeSelf;
originalTips[j] = val2.tips;
}
if (j < menu.categoryIcons.Length && (Object)(object)menu.categoryIcons[j] != (Object)null)
{
originalIcons[j] = menu.categoryIcons[j].sprite;
}
}
heading = val;
originalHeadingText = heading.text;
error = null;
return true;
}
private static Text FindHeading(RectTransform group)
{
Text[] componentsInChildren = ((Component)group).GetComponentsInChildren<Text>(true);
foreach (Text val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform.parent == (Object)(object)group)
{
return val;
}
}
return null;
}
private static List<int> GetOrderedButtonIds(Dictionary<int, UIButton> buttons)
{
List<int> list = new List<int>(buttons.Count);
HashSet<int> hashSet = new HashSet<int>();
if ((Object)(object)LDB.veges != (Object)null && ((ProtoSet<VegeProto>)(object)LDB.veges).dataArray != null)
{
VegeProto[] dataArray = ((ProtoSet<VegeProto>)(object)LDB.veges).dataArray;
foreach (VegeProto val in dataArray)
{
if (val != null && buttons.ContainsKey(((Proto)val).ID) && hashSet.Add(((Proto)val).ID))
{
list.Add(((Proto)val).ID);
}
}
}
foreach (int key in buttons.Keys)
{
if (hashSet.Add(key))
{
list.Add(key);
}
}
return list;
}
private static Sprite FindRepresentativeSprite(HashSet<int> vegetationIds, HashSet<int> excludedIds, out int representativeId)
{
representativeId = 0;
if ((Object)(object)LDB.veges == (Object)null || ((ProtoSet<VegeProto>)(object)LDB.veges).dataArray == null)
{
return null;
}
return FindRepresentativeSprite(vegetationIds, excludedIds, out representativeId, excludeUsed: true) ?? FindRepresentativeSprite(vegetationIds, excludedIds, out representativeId, excludeUsed: false);
}
private static Sprite FindRepresentativeSprite(HashSet<int> vegetationIds, HashSet<int> excludedIds, out int representativeId, bool excludeUsed)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Invalid comparison between Unknown and I4
representativeId = 0;
VegeProto[] dataArray = ((ProtoSet<VegeProto>)(object)LDB.veges).dataArray;
for (int i = 90; i < dataArray.Length; i++)
{
VegeProto val = dataArray[i];
if (val != null && vegetationIds.Contains(((Proto)val).ID) && (!excludeUsed || !excludedIds.Contains(((Proto)val).ID)) && (Object)(object)val.iconSprite != (Object)null && (int)val.Type != 8)
{
representativeId = ((Proto)val).ID;
return val.iconSprite;
}
}
return null;
}
private static void PlaceButton(UIButton button, RectTransform group, List<UIButton> destination)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
((Component)button).transform.SetParent((Transform)(object)group);
((Component)button).GetComponent<RectTransform>().anchoredPosition = new Vector2((float)(destination.Count % 12 * 50), (float)(-(destination.Count / 12) * 50 - 36));
destination.Add(button);
}
}
[HarmonyPatch]
internal static class VegetationModePatches
{
private static readonly MethodInfo SandboxToolsGetter = AccessTools.PropertyGetter(typeof(GameMain), "sandboxToolsEnabled");
private static readonly MethodInfo VegetationAvailabilityMethod = AccessTools.Method(typeof(VegetationModePatches), "IsVegetationToolAvailable", (Type[])null, (Type[])null);
private static readonly MethodInfo VectorOneGetter = AccessTools.PropertyGetter(typeof(Vector3), "one");
private static readonly MethodInfo VegetationScaleVectorMethod = AccessTools.Method(typeof(VegetationModePatches), "GetVegetationScaleVector", (Type[])null, (Type[])null);
private const float DefaultVegetationScaleStep = 0.1f;
private const float ShiftVegetationScaleStep = 0.5f;
private const float ControlVegetationScaleStep = 0.01f;
private const float MinimumVegetationScale = 0.1f;
private const float MaximumVegetationScale = 30f;
private const float VegetationScaleRepeatDelay = 0.3f;
private const float VegetationScaleRepeatInterval = 0.08f;
private static bool runtimeDisabled;
private static bool runtimeErrorLogged;
private static int selectedVegetationCategory;
private static int scaledVegetationProtoId;
private static float vegetationScale = 1f;
private static KeyCode heldVegetationScaleKey = (KeyCode)0;
private static float nextVegetationScaleRepeatTime;
internal static void ValidateTargets()
{
runtimeDisabled = false;
runtimeErrorLogged = false;
scaledVegetationProtoId = 0;
vegetationScale = 1f;
ResetVegetationScaleInput();
RequireMethod(typeof(UIFunctionPanel), "_OnUpdate");
RequireMethod(typeof(UIGame), "_OnUpdate");
RequireMethod(typeof(PlayerAction_Plant), "DetermineActive");
RequireMethod(typeof(UISandboxMenu), "_OnOpen");
RequireMethod(typeof(UISandboxMenu), "_OnUpdate");
RequireMethod(typeof(UISandboxMenu), "SetCurrentCategory");
RequireMethod(typeof(UISandboxMenu), "SetVegeLayout");
RequireMethod(typeof(UISandboxMenu), "OnCategoryButtonClick");
RequireMethod(typeof(UISandboxMenu), "OnChildButtonClick");
RequireMethod(typeof(PlayerAction_Plant), "SetHandVein");
RequireMethod(typeof(PlayerAction_Plant), "SetHandVege");
RequireMethod(typeof(PlayerAction_Plant), "SetRemovalMode");
RequireMethod(typeof(PlayerAction_Plant), "DeterminePlantPreview");
RequireMethod(typeof(PlayerAction_Plant), "DetermineRemovePreviews");
RequireMethod(typeof(PlayerAction_Plant), "PlantVeinFinally");
RequireMethod(typeof(PlayerAction_Plant), "PlantVegeFinally");
RequireMethod(typeof(PlayerControlGizmo), "SetPlantPreviewGizmo");
RequireField(typeof(UISandboxMenu), "vegeButtonDic");
RequireField(typeof(UISandboxMenu), "vegeButtonPrefab");
RequireField(typeof(UISandboxMenu), "lastTheme");
RequireField(typeof(UISandboxMenu), "actionPlant");
RequireField(typeof(UISandboxMenu), "veinFilterToggle");
RequireField(typeof(UISandboxMenu), "vegeFilterToggle");
RequireField(typeof(PlayerControlGizmo), "plantPreviewGizmo");
if (SandboxToolsGetter == null || VegetationAvailabilityMethod == null || VectorOneGetter == null || VegetationScaleVectorMethod == null)
{
throw new MissingMethodException("The sandbox permission getter or its replacement was not found.");
}
RequireSandboxCheckCount(typeof(UIFunctionPanel), "_OnUpdate", 3);
RequireSandboxCheckCount(typeof(UIGame), "_OnUpdate", 1);
RequireSandboxCheckCount(typeof(PlayerAction_Plant), "DetermineActive", 1);
}
private static void RequireMethod(Type type, string methodName)
{
if (AccessTools.Method(type, methodName, (Type[])null, (Type[])null) == null)
{
throw new MissingMethodException(type.FullName, methodName);
}
}
private static void RequireField(Type type, string fieldName)
{
if (AccessTools.Field(type, fieldName) == null)
{
throw new MissingFieldException(type.FullName, fieldName);
}
}
private static void RequireSandboxCheckCount(Type type, string methodName, int expectedCount)
{
MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
int num = 0;
foreach (CodeInstruction originalInstruction in PatchProcessor.GetOriginalInstructions((MethodBase)methodInfo, (ILGenerator)null))
{
if ((originalInstruction.opcode == OpCodes.Call || originalInstruction.opcode == OpCodes.Callvirt) && object.Equals(originalInstruction.operand, SandboxToolsGetter))
{
num++;
}
}
if (num != expectedCount)
{
throw new InvalidOperationException($"{type.FullName}.{methodName} contained {num} sandbox checks; " + $"expected {expectedCount}.");
}
}
private static bool IsVegetationToolAvailable()
{
if (GameMain.sandboxToolsEnabled)
{
return true;
}
if (runtimeDisabled)
{
return false;
}
GameData data = GameMain.data;
if (data != null && data.gameDesc != null)
{
return !data.gameDesc.isSandboxMode;
}
return false;
}
private static bool IsVegetationOnlyMode()
{
if (IsVegetationToolAvailable())
{
return !GameMain.sandboxToolsEnabled;
}
return false;
}
private static bool ShouldRestrictSandboxTools()
{
GameData data = GameMain.data;
if (!GameMain.sandboxToolsEnabled && data != null && data.gameDesc != null)
{
return !data.gameDesc.isSandboxMode;
}
return false;
}
private static bool IsAllowedCategory(int category)
{
if (!ShouldRestrictSandboxTools())
{
return true;
}
if (category != 0 && category != 10)
{
if (!runtimeDisabled)
{
return category == 3;
}
return false;
}
return true;
}
private static Vector3 GetVegetationScaleVector()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
if (!ShouldRestrictSandboxTools())
{
return Vector3.one;
}
return Vector3.one * vegetationScale;
}
private static void ConfigureVegetationRemoval(PlayerAction_Plant actionPlant)
{
if (actionPlant != null && ShouldRestrictSandboxTools())
{
actionPlant.veinRemovalFilter = false;
actionPlant.vegeRemovalFilter = true;
}
}
private static void UpdateVegetationScaleInput(PlayerAction_Plant actionPlant)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Invalid comparison between Unknown and I4
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (!ShouldRestrictSandboxTools() || actionPlant == null || actionPlant.handVegeProtoId <= 0 || actionPlant.handPlantPreview == null || VFInput.onGUI || VFInput.inputing || !Application.isFocused)
{
ResetVegetationScaleInput();
return;
}
bool key = Input.GetKey((KeyCode)113);
bool key2 = Input.GetKey((KeyCode)101);
if (key == key2)
{
ResetVegetationScaleInput();
return;
}
KeyCode val = (KeyCode)(key ? 113 : 101);
bool increase = (int)val == 113;
float unscaledTime = Time.unscaledTime;
if (Input.GetKeyDown(val) && heldVegetationScaleKey != val)
{
heldVegetationScaleKey = val;
nextVegetationScaleRepeatTime = unscaledTime + 0.3f;
ApplyVegetationScaleStep(increase);
}
else if (heldVegetationScaleKey == val && !(unscaledTime < nextVegetationScaleRepeatTime))
{
nextVegetationScaleRepeatTime = unscaledTime + 0.08f;
ApplyVegetationScaleStep(increase);
}
}
private static void ApplyVegetationScaleStep(bool increase)
{
bool controlHeld = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
bool shiftHeld = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
float vegetationScaleStep = GetVegetationScaleStep(controlHeld, shiftHeld);
vegetationScale = AdjustVegetationScale(vegetationScale, increase, vegetationScaleStep);
}
private static float GetVegetationScaleStep(bool controlHeld, bool shiftHeld)
{
if (controlHeld)
{
return 0.01f;
}
if (!shiftHeld)
{
return 0.1f;
}
return 0.5f;
}
private static float AdjustVegetationScale(float currentScale, bool increase, float step)
{
return Mathf.Clamp(Mathf.Round((currentScale + (increase ? step : (0f - step))) * 100f) / 100f, 0.1f, 30f);
}
private static void ResetVegetationScaleInput()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
heldVegetationScaleKey = (KeyCode)0;
nextVegetationScaleRepeatTime = 0f;
}
private static IEnumerable<CodeInstruction> ReplaceSandboxChecks(IEnumerable<CodeInstruction> instructions, int expectedCount, string targetName)
{
int replacedCount = 0;
foreach (CodeInstruction instruction in instructions)
{
if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && object.Equals(instruction.operand, SandboxToolsGetter))
{
instruction.opcode = OpCodes.Call;
instruction.operand = VegetationAvailabilityMethod;
replacedCount++;
}
yield return instruction;
}
if (replacedCount != expectedCount)
{
throw new InvalidOperationException($"{targetName} contained {replacedCount} sandbox checks; expected {expectedCount}. " + "The game method has changed, so the patch was not applied.");
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(UIFunctionPanel), "_OnUpdate")]
private static IEnumerable<CodeInstruction> UIFunctionPanelOnUpdateTranspiler(IEnumerable<CodeInstruction> instructions)
{
return ReplaceSandboxChecks(instructions, 3, "UIFunctionPanel._OnUpdate");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIFunctionPanel), "_OnUpdate")]
private static void UIFunctionPanelOnUpdatePostfix(UIFunctionPanel __instance)
{
if (IsVegetationOnlyMode())
{
GameHistoryData history = GameMain.history;
Player mainPlayer = GameMain.mainPlayer;
bool flag = history != null && mainPlayer != null && !history.TechUnlocked(1001) && !mainPlayer.sailing && !__instance.showSandBoxMenu;
if (__instance.needResearchTipGroup.activeSelf != flag)
{
__instance.needResearchTipGroup.SetActive(flag);
}
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(UIGame), "_OnUpdate")]
private static IEnumerable<CodeInstruction> UIGameOnUpdateTranspiler(IEnumerable<CodeInstruction> instructions)
{
return ReplaceSandboxChecks(instructions, 1, "UIGame._OnUpdate");
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(PlayerAction_Plant), "DetermineActive")]
private static IEnumerable<CodeInstruction> DetermineActiveTranspiler(IEnumerable<CodeInstruction> instructions)
{
return ReplaceSandboxChecks(instructions, 1, "PlayerAction_Plant.DetermineActive");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerAction_Plant), "DetermineActive")]
private static void DetermineActivePostfix(PlayerAction_Plant __instance, ref bool __result)
{
if (ShouldRestrictSandboxTools() && __instance.handVeinProtoId > 0)
{
__instance.SetHandVein(0);
__result = false;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerAction_Plant), "SetHandVege")]
private static void SetHandVegePostfix(PlayerAction_Plant __instance, int vegeProtoId)
{
if (!ShouldRestrictSandboxTools())
{
ResetVegetationScaleInput();
}
else if (vegeProtoId <= 0 || __instance.handVegeProtoId <= 0)
{
scaledVegetationProtoId = 0;
vegetationScale = 1f;
ResetVegetationScaleInput();
}
else if (scaledVegetationProtoId != __instance.handVegeProtoId)
{
scaledVegetationProtoId = __instance.handVegeProtoId;
vegetationScale = 1f;
ResetVegetationScaleInput();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerAction_Plant), "DeterminePlantPreview")]
private static void DeterminePlantPreviewPostfix(PlayerAction_Plant __instance)
{
UpdateVegetationScaleInput(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerAction_Plant), "DetermineRemovePreviews")]
private static void DetermineRemovePreviewsPrefix(PlayerAction_Plant __instance)
{
ConfigureVegetationRemoval(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerControlGizmo), "SetPlantPreviewGizmo")]
private static void SetPlantPreviewGizmoPostfix(ModelPreview preview, ModelGizmo ___plantPreviewGizmo)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (ShouldRestrictSandboxTools() && preview != null && preview.vegeProtoId > 0 && (Object)(object)___plantPreviewGizmo != (Object)null)
{
((Component)___plantPreviewGizmo).transform.localScale = GetVegetationScaleVector();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UISandboxMenu), "_OnOpen")]
private static void SandboxMenuOnOpenPostfix(UISandboxMenu __instance)
{
selectedVegetationCategory = 0;
ApplyMenuMode(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UISandboxMenu), "_OnUpdate")]
private static void SandboxMenuOnUpdatePostfix(UISandboxMenu __instance, PlayerAction_Plant ___actionPlant, UIToggle ___veinFilterToggle, UIToggle ___vegeFilterToggle)
{
if (IsVegetationOnlyMode() && __instance.currentCategory == 3 && VegetationCategoryCatalog.IsCustomCategory(selectedVegetationCategory))
{
VegetationCategoryUi.HideUnselectedVegetationGroup(__instance);
VegetationCategoryUi.UpdateScaleDisplay(selectedVegetationCategory, ___actionPlant != null && ___actionPlant.handVegeProtoId > 0, vegetationScale);
}
if (IsVegetationOnlyMode() && __instance.currentCategory == 10)
{
ConfigureVegetationRemoval(___actionPlant);
if ((Object)(object)___veinFilterToggle != (Object)null)
{
___veinFilterToggle.isOn = false;
if ((Object)(object)___veinFilterToggle.toggle != (Object)null)
{
((Selectable)___veinFilterToggle.toggle).interactable = false;
}
}
if ((Object)(object)___vegeFilterToggle != (Object)null)
{
___vegeFilterToggle.isOn = true;
if ((Object)(object)___vegeFilterToggle.toggle != (Object)null)
{
((Selectable)___vegeFilterToggle.toggle).interactable = false;
}
}
}
else if (!IsVegetationOnlyMode())
{
if ((Object)(object)___veinFilterToggle?.toggle != (Object)null)
{
((Selectable)___veinFilterToggle.toggle).interactable = true;
}
if ((Object)(object)___vegeFilterToggle?.toggle != (Object)null)
{
((Selectable)___vegeFilterToggle.toggle).interactable = true;
}
}
}
private static void ApplyMenuMode(UISandboxMenu menu)
{
if (GameMain.sandboxToolsEnabled)
{
VegetationCategoryUi.RestoreNativeChrome(menu);
return;
}
if (!IsVegetationOnlyMode())
{
VegetationCategoryUi.HideCategoryButtons(menu);
return;
}
VegetationCategoryCatalog.Rebuild();
if (!VegetationCategoryUi.TryApplyRegularChrome(menu, selectedVegetationCategory, out var error))
{
DisableAtRuntime(menu, error);
}
}
private static void DisableAtRuntime(UISandboxMenu menu, string reason)
{
runtimeDisabled = true;
selectedVegetationCategory = 0;
menu.SetCurrentCategory(0);
VegetationCategoryUi.HideCategoryButtons(menu);
if (!runtimeErrorLogged)
{
runtimeErrorLogged = true;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("The native vegetation category UI was incompatible. Normal-mode vegetation placement has been disabled. " + reason));
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UISandboxMenu), "SetCurrentCategory")]
private static bool SetCurrentCategoryPrefix(int category)
{
return IsAllowedCategory(category);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UISandboxMenu), "OnCategoryButtonClick")]
private static bool OnCategoryButtonClickPrefix(UISandboxMenu __instance, int index)
{
if (!ShouldRestrictSandboxTools())
{
return true;
}
if (index == 10)
{
selectedVegetationCategory = 0;
return true;
}
if (runtimeDisabled || !VegetationCategoryCatalog.IsCustomCategory(index))
{
return false;
}
bool flag = __instance.currentCategory == 3 && selectedVegetationCategory == index;
selectedVegetationCategory = ((!flag) ? index : 0);
__instance.SetCurrentCategory((!flag) ? 3 : 0);
if (!IsVegetationOnlyMode())
{
return false;
}
if (!VegetationCategoryUi.TryApplyRegularChrome(__instance, selectedVegetationCategory, out var error))
{
DisableAtRuntime(__instance, error);
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UISandboxMenu), "SetVegeLayout")]
private static bool SetVegeLayoutPrefix(UISandboxMenu __instance, Dictionary<int, UIButton> ___vegeButtonDic, UIButton ___vegeButtonPrefab, ref int ___lastTheme)
{
if (!IsVegetationOnlyMode())
{
return true;
}
___lastTheme = 0;
if (!VegetationCategoryUi.TrySetVegetationLayout(__instance, ___vegeButtonDic, ___vegeButtonPrefab, selectedVegetationCategory, out var error))
{
DisableAtRuntime(__instance, error);
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UISandboxMenu), "OnChildButtonClick")]
private static bool OnChildButtonClickPrefix(UISandboxMenu __instance)
{
if (ShouldRestrictSandboxTools())
{
if (!runtimeDisabled)
{
return __instance.currentCategory == 3;
}
return false;
}
return true;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerAction_Plant), "SetHandVein")]
private static bool SetHandVeinPrefix(int veinProtoId)
{
if (ShouldRestrictSandboxTools())
{
return veinProtoId == 0;
}
return true;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerAction_Plant), "SetRemovalMode")]
private static void SetRemovalModePostfix(PlayerAction_Plant __instance)
{
ConfigureVegetationRemoval(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerAction_Plant), "PlantVeinFinally")]
private static bool PlantVeinFinallyPrefix()
{
return !ShouldRestrictSandboxTools();
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(PlayerAction_Plant), "PlantVegeFinally")]
private static IEnumerable<CodeInstruction> PlantVegeFinallyTranspiler(IEnumerable<CodeInstruction> instructions)
{
int replacedCount = 0;
foreach (CodeInstruction instruction in instructions)
{
if (CodeInstructionExtensions.Calls(instruction, VectorOneGetter))
{
instruction.opcode = OpCodes.Call;
instruction.operand = VegetationScaleVectorMethod;
replacedCount++;
}
yield return instruction;
}
if (replacedCount != 2)
{
throw new InvalidOperationException("PlayerAction_Plant.PlantVegeFinally contained " + $"{replacedCount} vegetation scale initializers; expected 2. " + "The game method has changed, so scalable vegetation was not enabled.");
}
}
}