using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Components; using UnityEngine.Localization.Tables; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("RodLockerBepInEx")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RodLockerBepInEx")] [assembly: AssemblyTitle("RodLockerBepInEx")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RodLockerBepInEx { [BepInPlugin("legoless.RodLocker", "Rod Locker", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "legoless.RodLocker"; public const string PluginName = "Rod Locker"; public const string PluginVersion = "1.0.0"; private Harmony harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; RodLockerRuntime.PluginAssembly = Assembly.GetExecutingAssembly(); harmony = new Harmony("legoless.RodLocker"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rod Locker BepInEx Edition loaded. No game files are modified by this plugin DLL."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } internal static class RodLockerRuntime { private sealed class RodDefinition { public string Id { get; } public Sprite Sprite { get; } public RodDefinition(string id, Sprite sprite) { Id = id; Sprite = sprite; } } private const string BlackstoneDockId = "dock.outcast-isle"; private const string RodLockerDestinationId = "destination.rod-locker"; private const string RodLockerTitleKey = "destination.rod-locker"; private const GridKey RodLockerGridKey = 459001; private static readonly FieldInfo DestinationButtonPrefabField = AccessTools.Field(typeof(DockUI), "destinationButtonPrefab"); private static readonly FieldInfo DestinationButtonContainerField = AccessTools.Field(typeof(DockUI), "destinationButtonContainer"); private static readonly FieldInfo DestinationButtonObjectsField = AccessTools.Field(typeof(DockUI), "destinationButtonObjects"); private static readonly FieldInfo DestinationButtonsField = AccessTools.Field(typeof(DockUI), "destinationButtons"); private static readonly FieldInfo DockDestinationsField = AccessTools.Field(typeof(Dock), "destinations"); private static readonly FieldInfo BaseDestinationIdField = AccessTools.Field(typeof(BaseDestination), "id"); private static readonly FieldInfo BaseDestinationTitleKeyField = AccessTools.Field(typeof(BaseDestination), "titleKey"); private static readonly FieldInfo BaseDestinationSpeakerRootNodeOverrideField = AccessTools.Field(typeof(BaseDestination), "speakerRootNodeOverride"); private static readonly FieldInfo BaseDestinationAlwaysShowField = AccessTools.Field(typeof(BaseDestination), "alwaysShow"); private static readonly FieldInfo BaseDestinationIsIndoorsField = AccessTools.Field(typeof(BaseDestination), "isIndoors"); private static readonly FieldInfo BaseDestinationIconField = AccessTools.Field(typeof(BaseDestination), "icon"); private static readonly FieldInfo BaseDestinationLoopSfxField = AccessTools.Field(typeof(BaseDestination), "loopSFX"); private static readonly FieldInfo BaseDestinationVisitSfxField = AccessTools.Field(typeof(BaseDestination), "visitSFX"); private static readonly FieldInfo BaseDestinationVCamField = AccessTools.Field(typeof(BaseDestination), "vCam"); private static readonly FieldInfo BaseDestinationHighlightConditionsField = AccessTools.Field(typeof(BaseDestination), "highlightConditions"); private static readonly FieldInfo BaseDestinationPlayerInventoryTabIndexesField = AccessTools.Field(typeof(BaseDestination), "playerInventoryTabIndexesToShow"); private static readonly FieldInfo MarketDestinationItemTypesBoughtField = AccessTools.Field(typeof(MarketDestination), "itemTypesBought"); private static readonly FieldInfo MarketDestinationItemSubtypesBoughtField = AccessTools.Field(typeof(MarketDestination), "itemSubtypesBought"); private static readonly FieldInfo MarketDestinationBulkItemTypesBoughtField = AccessTools.Field(typeof(MarketDestination), "bulkItemTypesBought"); private static readonly FieldInfo MarketDestinationBulkItemSubtypesBoughtField = AccessTools.Field(typeof(MarketDestination), "bulkItemSubtypesBought"); private static readonly FieldInfo MarketDestinationSpecificItemsBoughtField = AccessTools.Field(typeof(MarketDestination), "specificItemsBought"); private static readonly FieldInfo MarketDestinationSellValueModifierField = AccessTools.Field(typeof(MarketDestination), "sellValueModifier"); private static readonly FieldInfo MarketDestinationAllowSellIfGridFullField = AccessTools.Field(typeof(MarketDestination), "allowSellIfGridFull"); private static readonly FieldInfo MarketDestinationAllowStorageAccessField = AccessTools.Field(typeof(MarketDestination), "allowStorageAccess"); private static readonly FieldInfo MarketDestinationAllowRepairsField = AccessTools.Field(typeof(MarketDestination), "allowRepairs"); private static readonly FieldInfo MarketDestinationAllowBulkSellField = AccessTools.Field(typeof(MarketDestination), "allowBulkSell"); private static readonly FieldInfo MarketDestinationBulkSellPromptStringField = AccessTools.Field(typeof(MarketDestination), "bulkSellPromptString"); private static readonly FieldInfo MarketDestinationBulkSellNotificationStringField = AccessTools.Field(typeof(MarketDestination), "bulkSellNotificationString"); private static readonly FieldInfo DestinationButtonTextField = AccessTools.Field(typeof(DestinationButton), "textField"); private static readonly FieldInfo MarketTitleStringField = AccessTools.Field(typeof(MarketDestinationUI), "localizedTitleString"); private static readonly FieldInfo BaseDestinationUIDestinationField = AccessTools.Field(typeof(BaseDestinationUI), "destination"); private static readonly FieldInfo ItemManagerAllItemsField = AccessTools.Field(typeof(ItemManager), "allItems"); private static readonly FieldInfo PlatformSpriteOverridesField = AccessTools.Field(typeof(SpatialItemData), "platformSpecificSpriteOverrides"); private static readonly FieldInfo ItemOwnPrerequisitesField = AccessTools.Field(typeof(SpatialItemData), "itemOwnPrerequisites"); private static readonly FieldInfo ResearchPrerequisitesField = AccessTools.Field(typeof(SpatialItemData), "researchPrerequisites"); private static readonly FieldInfo ResearchPointsRequiredField = AccessTools.Field(typeof(SpatialItemData), "researchPointsRequired"); private static readonly FieldInfo BuyableWithoutResearchField = AccessTools.Field(typeof(SpatialItemData), "buyableWithoutResearch"); private static readonly FieldInfo ResearchIsForRecipeField = AccessTools.Field(typeof(SpatialItemData), "researchIsForRecipe"); private static readonly FieldInfo GridMainItemTypeField = AccessTools.Field(typeof(GridConfiguration), "mainItemType"); private static readonly FieldInfo GridMainItemSubtypeField = AccessTools.Field(typeof(GridConfiguration), "mainItemSubtype"); private static readonly FieldInfo GridItemsBelongToPlayerField = AccessTools.Field(typeof(GridConfiguration), "itemsInThisBelongToPlayer"); private static readonly FieldInfo GridCanAddItemsInQuestModeField = AccessTools.Field(typeof(GridConfiguration), "canAddItemsInQuestMode"); private static readonly FieldInfo GridHasUnderlayField = AccessTools.Field(typeof(GridConfiguration), "hasUnderlay"); private static readonly string[] RodItemIds = new string[7] { "legoless.rodlocker.playstation", "legoless.rodlocker.xbox", "legoless.rodlocker.switch", "legoless.rodlocker.steam", "legoless.rodlocker.gog", "legoless.rodlocker.ios", "legoless.rodlocker.android" }; private static readonly Dictionary RodSpriteResourceNames = new Dictionary(StringComparer.Ordinal) { { "legoless.rodlocker.playstation", "RodLockerBepInEx.Assets.legoless.rodlocker.playstation.png" }, { "legoless.rodlocker.xbox", "RodLockerBepInEx.Assets.legoless.rodlocker.xbox.png" }, { "legoless.rodlocker.switch", "RodLockerBepInEx.Assets.legoless.rodlocker.switch.png" }, { "legoless.rodlocker.steam", "RodLockerBepInEx.Assets.legoless.rodlocker.steam.png" }, { "legoless.rodlocker.gog", "RodLockerBepInEx.Assets.legoless.rodlocker.gog.png" }, { "legoless.rodlocker.ios", "RodLockerBepInEx.Assets.legoless.rodlocker.ios.png" }, { "legoless.rodlocker.android", "RodLockerBepInEx.Assets.legoless.rodlocker.android.png" } }; private static readonly Dictionary TitleTranslations = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "en", "Rod Locker" }, { "fr", "Casier à cannes" }, { "de", "Angelrutenschrank" }, { "it", "Armadietto portacanne" }, { "es", "Taquilla de cañas" }, { "pl", "Szafka na wędki" }, { "ru", "Шкафчик для удочек" }, { "pt-BR", "Armário de varas" }, { "ja-JP", "ロッドロッカー" }, { "ko-KR", "낙싯대 보관함" }, { "zh-Hans", "鱼竿柜" }, { "zh-Hant", "釣竿櫃" } }; private static bool loggedInjection; private static bool registeredItems; private static bool loadedEmbeddedSprites; private static MarketDestination rodLockerDestination; private static GridConfiguration rodLockerGridConfig; private static Sprite rodIconSprite; private static readonly Dictionary RodSprites = new Dictionary(StringComparer.Ordinal); internal static Assembly PluginAssembly { get; set; } internal static BaseDestination EnsureRodLockerDestination(Dock dock) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Expected O, but got Unknown if ((Object)(object)dock == (Object)null || (Object)(object)dock.Data == (Object)null || dock.Data.Id != "dock.outcast-isle") { return null; } EnsureRuntimeData(); EnsureRodLockerGrid(); if ((Object)(object)rodLockerDestination != (Object)null) { return (BaseDestination)(object)rodLockerDestination; } try { BaseDestination val = GetDockDestinations(dock)?.FirstOrDefault((Func)((BaseDestination destination) => (Object)(object)destination != (Object)null && (destination.Id == "destination.outcast-yard" || ((Object)((Component)destination).gameObject).name == "Workshop"))); MarketDestination val2 = (MarketDestination)(object)((val is MarketDestination) ? val : null); Transform val3 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.parent : ((Component)dock).transform); GameObject val4 = new GameObject("Rod Locker Destination"); val4.transform.SetParent(val3, false); val4.transform.localPosition = (((Object)(object)val != (Object)null) ? (((Component)val).transform.localPosition + new Vector3(0f, 1.25f, 0f)) : Vector3.zero); MarketDestination val5 = val4.AddComponent(); BaseDestinationIdField.SetValue(val5, "destination.rod-locker"); BaseDestinationTitleKeyField.SetValue(val5, CreateLocalizedString("destination.rod-locker")); BaseDestinationSpeakerRootNodeOverrideField.SetValue(val5, string.Empty); BaseDestinationAlwaysShowField.SetValue(val5, true); BaseDestinationIsIndoorsField.SetValue(val5, true); BaseDestinationIconField.SetValue(val5, ((Object)(object)rodIconSprite != (Object)null) ? rodIconSprite : (((Object)(object)val != (Object)null) ? val.Icon : null)); BaseDestinationLoopSfxField.SetValue(val5, ((Object)(object)val2 != (Object)null) ? BaseDestinationLoopSfxField.GetValue(val2) : null); BaseDestinationVisitSfxField.SetValue(val5, ((Object)(object)val2 != (Object)null) ? BaseDestinationVisitSfxField.GetValue(val2) : null); BaseDestinationVCamField.SetValue(val5, ((Object)(object)val != (Object)null) ? val.VCam : null); BaseDestinationHighlightConditionsField.SetValue(val5, new List()); ((BaseDestination)val5).selectOnLeft = new List(); ((BaseDestination)val5).selectOnRight = new List(); ((BaseDestination)val5).selectOnUp = new List(); ((BaseDestination)val5).selectOnDown = (((Object)(object)val != (Object)null) ? new List { val } : new List()); List value = (((Object)(object)val2 != (Object)null) ? new List((List)BaseDestinationPlayerInventoryTabIndexesField.GetValue(val2)) : new List { 0, 1, 2 }); BaseDestinationPlayerInventoryTabIndexesField.SetValue(val5, value); MarketDestinationItemTypesBoughtField.SetValue(val5, (object)(ItemType)2); MarketDestinationItemSubtypesBoughtField.SetValue(val5, (object)(ItemSubtype)4); MarketDestinationBulkItemTypesBoughtField.SetValue(val5, (object)(ItemType)0); MarketDestinationBulkItemSubtypesBoughtField.SetValue(val5, (object)(ItemSubtype)0); MarketDestinationSpecificItemsBoughtField.SetValue(val5, Array.Empty()); MarketDestinationSellValueModifierField.SetValue(val5, 0f); MarketDestinationAllowSellIfGridFullField.SetValue(val5, false); MarketDestinationAllowStorageAccessField.SetValue(val5, true); MarketDestinationAllowRepairsField.SetValue(val5, false); MarketDestinationAllowBulkSellField.SetValue(val5, false); MarketDestinationBulkSellPromptStringField.SetValue(val5, string.Empty); MarketDestinationBulkSellNotificationStringField.SetValue(val5, string.Empty); val5.marketTabs = new List { new MarketTabConfig { gridKey = (GridKey)459001, tabSprite = (((Object)(object)rodIconSprite != (Object)null) ? rodIconSprite : (((Object)(object)val != (Object)null) ? val.Icon : null)), titleKey = CreateLocalizedString("destination.rod-locker"), isUnlockedBasedOnDialogue = false, unlockDialogueNodes = new List() } }; rodLockerDestination = val5; return (BaseDestination)(object)val5; } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to create Rod Locker destination: {arg}"); return null; } } internal static void AddRodLockerButton(DockUI dockUi, Dock dock) { if ((Object)(object)dockUi == (Object)null || (Object)(object)dock == (Object)null || (Object)(object)dock.Data == (Object)null || dock.Data.Id != "dock.outcast-isle") { return; } BaseDestination val = EnsureRodLockerDestination(dock); if ((Object)(object)val == (Object)null) { return; } try { List list = DestinationButtonsField.GetValue(dockUi) as List; if (list != null && list.Any((DestinationButton button) => (Object)(object)button != (Object)null && (Object)(object)button.destination != (Object)null && button.destination.Id == "destination.rod-locker")) { return; } object? value = DestinationButtonPrefabField.GetValue(dockUi); GameObject val2 = (GameObject)((value is GameObject) ? value : null); object? value2 = DestinationButtonContainerField.GetValue(dockUi); Transform val3 = (Transform)((value2 is Transform) ? value2 : null); List list2 = DestinationButtonObjectsField.GetValue(dockUi) as List; if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { Plugin.Log.LogError((object)"Rod Locker could not find the vanilla destination button prefab/container."); return; } GameObject val4 = Object.Instantiate(val2, val3); DestinationButton component = val4.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val4); Plugin.Log.LogError((object)"Rod Locker destination button prefab did not contain DestinationButton."); return; } component.Init(val); SetDestinationButtonText(component); list?.Add(component); list2?.Add(val4); if (!loggedInjection) { Plugin.Log.LogInfo((object)$"Rod Locker UI button added to Blackstone. StoredDestinations={GetDockDestinations(dock)?.Count ?? 0}, BoatActionsReady={(Object)(object)dock.boatActionsDestination != (Object)null}"); loggedInjection = true; } } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to add Rod Locker UI button: {arg}"); } } internal static void ResetCachedDestination() { rodLockerDestination = null; loggedInjection = false; } internal static void EnsureRuntimeData() { LoadEmbeddedSprites(); GameManager instance = GameManager.Instance; RegisterRodItems((instance != null) ? instance.ItemManager : null); EnsureRodLockerGridConfig(); } internal static void RegisterRodItems(ItemManager itemManager) { //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) LoadEmbeddedSprites(); if ((Object)(object)itemManager == (Object)null || !itemManager.HasLoaded()) { return; } if (!(ItemManagerAllItemsField.GetValue(itemManager) is List list)) { Plugin.Log.LogWarning((object)"Could not access ItemManager item list for Rod Locker registration."); } else { if (registeredItems && HasAllRodItems(list)) { return; } RodItemData itemDataById = itemManager.GetItemDataById("rod21"); if ((Object)(object)itemDataById == (Object)null) { Plugin.Log.LogWarning((object)"Could not find vanilla rod21 Custom Rod data."); return; } rodIconSprite = (((Object)(object)((ItemData)itemDataById).itemTypeIcon != (Object)null) ? ((ItemData)itemDataById).itemTypeIcon : ((SpatialItemData)itemDataById).GetSprite()); RodDefinition[] array = RodItemIds.Select((string itemId) => new RodDefinition(itemId, GetRodSprite(itemId))).ToArray(); int num = 0; RodDefinition[] array2 = array; foreach (RodDefinition definition in array2) { if ((Object)(object)definition.Sprite == (Object)null) { Plugin.Log.LogWarning((object)("Skipping " + definition.Id + ": no sprite was available.")); } else if (!list.Any((ItemData item) => (Object)(object)item != (Object)null && item.id == definition.Id)) { RodItemData val = Object.Instantiate(itemDataById); ((Object)val).name = definition.Id; ((ItemData)val).id = definition.Id; ((SpatialItemData)val).sprite = definition.Sprite; ((SpatialItemData)val).itemColor = Color32.op_Implicit(new Color32((byte)49, (byte)49, (byte)49, byte.MaxValue)); ((SpatialItemData)val).value = default(decimal); ((SpatialItemData)val).sellOverrideValue = default(decimal); val.fishingSpeedModifier = 0.4f; ((HarvesterItemData)val).harvestableTypes = (HarvestableType[])(object)new HarvestableType[1] { (HarvestableType)1 }; ((HarvesterItemData)val).aberrationBonus = 0f; ((ItemData)val).itemType = (ItemType)2; ((ItemData)val).itemSubtype = (ItemSubtype)4; ((SpatialItemData)val).damageMode = (DamageMode)2; ((SpatialItemData)val).moveMode = (MoveMode)1; ((ItemData)val).entitlementsRequired = new List(); PlatformSpriteOverridesField.SetValue(val, new Dictionary()); ItemOwnPrerequisitesField.SetValue(val, new List()); ResearchPrerequisitesField.SetValue(val, new List()); ResearchPointsRequiredField.SetValue(val, 0); BuyableWithoutResearchField.SetValue(val, false); ResearchIsForRecipeField.SetValue(val, false); list.Add((ItemData)(object)val); num++; } } registeredItems = HasAllRodItems(list); Plugin.Log.LogInfo((object)$"Rod Locker registered custom rod item data. Added={num}, Present={CountRodItems(list)}/{RodItemIds.Length}"); } } internal static void EnsureRodLockerGrid() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown EnsureRuntimeData(); GameManager instance = GameManager.Instance; SaveData val = ((instance != null) ? instance.SaveData : null); if (val != null && !((Object)(object)rodLockerGridConfig == (Object)null)) { if (val.grids == null) { val.grids = new Dictionary(); } if (!val.grids.TryGetValue((GridKey)459001, out var value) || value == null) { value = new SerializableGrid(); val.grids[(GridKey)459001] = value; value.Init(rodLockerGridConfig, false); } else if ((Object)(object)value.GridConfiguration == (Object)null) { value.Init(rodLockerGridConfig, false); } RemoveAlreadyTakenStock(value); AddMissingStock(value); } } internal static bool IsRodLockerDestination(BaseDestination destination) { if ((Object)(object)destination != (Object)null) { return destination.Id == "destination.rod-locker"; } return false; } internal static bool IsRodLockerGrid(GridKey gridKey) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 return (int)gridKey == 459001; } internal static void SetDestinationButtonText(DestinationButton button) { if (!((Object)(object)button == (Object)null) && IsRodLockerDestination(button.destination)) { object? value = DestinationButtonTextField.GetValue(button); TextMeshProUGUI val = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null); if ((Object)(object)val != (Object)null) { ((TMP_Text)val).text = GetTranslatedTitle(); } } } internal static void SetMarketTitle(MarketDestinationUI ui) { if (!((Object)(object)ui == (Object)null) && IsRodLockerMarketUI(ui)) { object? value = MarketTitleStringField.GetValue(ui); LocalizeStringEvent val = (LocalizeStringEvent)((value is LocalizeStringEvent) ? value : null); TextMeshProUGUI val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 != (Object)null) { ((TMP_Text)val2).text = GetTranslatedTitle(); } } } internal static bool IsRodLockerMarketUI(MarketDestinationUI ui) { if ((Object)(object)ui == (Object)null) { return false; } object? obj = BaseDestinationUIDestinationField?.GetValue(ui); return IsRodLockerDestination((BaseDestination)((obj is BaseDestination) ? obj : null)); } internal static string GetTranslatedTitle() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) string text = "en"; try { GameManager instance = GameManager.Instance; object obj; if (instance == null) { obj = null; } else { LanguageManager languageManager = instance.LanguageManager; if (languageManager == null) { obj = null; } else { Locale locale = languageManager.GetLocale(); if (locale == null) { obj = null; } else { LocaleIdentifier identifier = locale.Identifier; obj = ((LocaleIdentifier)(ref identifier)).Code; } } } if (obj == null) { obj = text; } text = (string)obj; } catch { } if (TitleTranslations.TryGetValue(text, out var value)) { return value; } string key = text.Split(new char[1] { '-' })[0]; if (!TitleTranslations.TryGetValue(key, out value)) { return TitleTranslations["en"]; } return value; } private static void EnsureRodLockerGridConfig() { if (!((Object)(object)rodLockerGridConfig != (Object)null)) { GameManager instance = GameManager.Instance; GameConfigData val = ((instance != null) ? instance.GameConfigData : null); GridConfiguration val2 = (((Object)(object)val != (Object)null) ? val.GetGridConfigForKey((GridKey)21) : null); rodLockerGridConfig = (((Object)(object)val2 != (Object)null) ? Object.Instantiate(val2) : ScriptableObject.CreateInstance()); ((Object)rodLockerGridConfig).name = "legoless.rodlocker.grid"; rodLockerGridConfig.columns = 7; rodLockerGridConfig.rows = 2; rodLockerGridConfig.cellGroupConfigs = new List(); GridMainItemTypeField.SetValue(rodLockerGridConfig, (object)(ItemType)2); GridMainItemSubtypeField.SetValue(rodLockerGridConfig, (object)(ItemSubtype)4); GridItemsBelongToPlayerField.SetValue(rodLockerGridConfig, false); GridCanAddItemsInQuestModeField.SetValue(rodLockerGridConfig, false); GridHasUnderlayField.SetValue(rodLockerGridConfig, false); } } private static List GetDockDestinations(Dock dock) { if (!((Object)(object)dock != (Object)null)) { return null; } return DockDestinationsField.GetValue(dock) as List; } private static bool HasAllRodItems(List allItems) { return CountRodItems(allItems) == RodItemIds.Length; } private static int CountRodItems(List allItems) { if (allItems == null) { return 0; } return RodItemIds.Count((string itemId) => allItems.Any((ItemData item) => (Object)(object)item != (Object)null && item.id == itemId)); } private static void RemoveAlreadyTakenStock(SerializableGrid grid) { foreach (SpatialItemInstance item in grid.spatialItems.Where((SpatialItemInstance item) => item != (SpatialItemInstance)null && RodItemIds.Contains(((ItemInstance)item).id) && HasRodLockerItemBeenTaken(((ItemInstance)item).id)).ToList()) { grid.RemoveObjectFromGridData(item, false); } } private static void AddMissingStock(SerializableGrid grid) { GameManager instance = GameManager.Instance; ItemManager val = ((instance != null) ? instance.ItemManager : null); if ((Object)(object)val == (Object)null) { return; } HashSet hashSet = new HashSet(from item in grid.spatialItems where item != (SpatialItemInstance)null select ((ItemInstance)item).id); string[] rodItemIds = RodItemIds; foreach (string text in rodItemIds) { if (!hashSet.Contains(text) && !HasRodLockerItemBeenTaken(text)) { SpatialItemData itemDataById = val.GetItemDataById(text); if ((Object)(object)itemDataById == (Object)null) { Plugin.Log.LogWarning((object)("Could not stock " + text + ": item data is not registered.")); } else if (grid.FindSpaceAndAddObjectToGridData(itemDataById, false, (Action)null)) { hashSet.Add(text); } else { Plugin.Log.LogWarning((object)("Could not place " + text + " in the Rod Locker grid.")); } } } } private static bool HasRodLockerItemBeenTaken(string itemId) { GameManager instance = GameManager.Instance; return (((instance != null) ? instance.SaveData : null)?.itemTransactions?.Any((SerializedItemTransaction transaction) => transaction != null && transaction.itemId == itemId && transaction.bought > 0)).GetValueOrDefault(); } private static LocalizedString CreateLocalizedString(string key) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return new LocalizedString(TableReference.op_Implicit(LanguageManager.STRING_TABLE), TableEntryReference.op_Implicit(key)); } private static Sprite GetRodSprite(string itemId) { LoadEmbeddedSprites(); if (!RodSprites.TryGetValue(itemId, out var value)) { return null; } return value; } private static void LoadEmbeddedSprites() { if (loadedEmbeddedSprites) { return; } foreach (KeyValuePair rodSpriteResourceName in RodSpriteResourceNames) { Sprite val = LoadEmbeddedSprite(rodSpriteResourceName.Value, rodSpriteResourceName.Key + ".sprite"); if ((Object)(object)val != (Object)null) { RodSprites[rodSpriteResourceName.Key] = val; } } loadedEmbeddedSprites = true; Plugin.Log.LogInfo((object)$"Rod Locker loaded {RodSprites.Count}/{RodSpriteResourceNames.Count} embedded rod sprites."); } private static Sprite LoadEmbeddedSprite(string resourceName, string spriteName) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) using Stream stream = PluginAssembly.GetManifestResourceStream(resourceName); if (stream == null) { Plugin.Log.LogError((object)("Missing embedded sprite resource: " + resourceName)); return null; } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Object)val).name = spriteName.Replace(".sprite", ".texture"); if (!ImageConversion.LoadImage(val, array)) { Plugin.Log.LogError((object)("Failed to load embedded sprite resource: " + resourceName)); return null; } ((Texture)val).filterMode = (FilterMode)1; Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = spriteName; return obj; } } [HarmonyPatch(typeof(ItemManager), "OnItemDataAddressablesLoaded")] internal static class ItemManagerLoadedPatch { private static void Postfix(ItemManager __instance) { RodLockerRuntime.RegisterRodItems(__instance); RodLockerRuntime.EnsureRodLockerGrid(); } } [HarmonyPatch(typeof(GameManager), "BeginGame")] internal static class GameManagerBeginGamePatch { private static void Postfix() { RodLockerRuntime.ResetCachedDestination(); RodLockerRuntime.EnsureRuntimeData(); RodLockerRuntime.EnsureRodLockerGrid(); } } [HarmonyPatch(typeof(GameConfigData), "GetGridConfigForKey")] internal static class GameConfigDataGetGridConfigPatch { private static void Postfix(GridKey key, ref GridConfiguration __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (RodLockerRuntime.IsRodLockerGrid(key)) { RodLockerRuntime.EnsureRuntimeData(); GameManager instance = GameManager.Instance; SaveData val = ((instance != null) ? instance.SaveData : null); if (val != null && val.grids.TryGetValue(key, out var value)) { __result = value.GridConfiguration; } } } } [HarmonyPatch(typeof(DockUI), "ShowUIWithDelay")] internal static class DockUIShowUIWithDelayPatch { private static void Postfix(DockUI __instance, Dock dock, ref IEnumerator __result) { __result = AddRodLockerButtonAfterVanillaUI(__instance, dock, __result); } private static IEnumerator AddRodLockerButtonAfterVanillaUI(DockUI dockUi, Dock dock, IEnumerator original) { while (true) { object current; try { if (!original.MoveNext()) { break; } current = original.Current; goto IL_004f; } catch (Exception arg) { Plugin.Log.LogError((object)$"Vanilla DockUI.ShowUIWithDelay failed before Rod Locker injection: {arg}"); yield break; } IL_004f: yield return current; } (original as IDisposable)?.Dispose(); RodLockerRuntime.AddRodLockerButton(dockUi, dock); } } [HarmonyPatch(typeof(DestinationButton), "Init")] internal static class DestinationButtonInitPatch { private static void Postfix(DestinationButton __instance) { if ((Object)(object)__instance != (Object)null && RodLockerRuntime.IsRodLockerDestination(__instance.destination)) { RodLockerRuntime.SetDestinationButtonText(__instance); ((MonoBehaviour)__instance).StartCoroutine(SetTextNextFrame(__instance)); } } private static IEnumerator SetTextNextFrame(DestinationButton button) { yield return null; RodLockerRuntime.SetDestinationButtonText(button); } } [HarmonyPatch(typeof(MarketDestinationUI), "ShowMainUI")] internal static class MarketDestinationUIShowMainUIPatch { private static void Prefix(MarketDestinationUI __instance) { if (RodLockerRuntime.IsRodLockerMarketUI(__instance)) { RodLockerRuntime.EnsureRodLockerGrid(); } } private static void Postfix(MarketDestinationUI __instance) { if (RodLockerRuntime.IsRodLockerMarketUI(__instance)) { RodLockerRuntime.SetMarketTitle(__instance); ((MonoBehaviour)__instance).StartCoroutine(SetTitleNextFrame(__instance)); } } private static IEnumerator SetTitleNextFrame(MarketDestinationUI ui) { yield return null; RodLockerRuntime.SetMarketTitle(ui); } } [HarmonyPatch(typeof(MarketDestinationUI), "OnMarketTabChanged")] internal static class MarketDestinationUIOnMarketTabChangedPatch { private static void Postfix(MarketDestinationUI __instance) { RodLockerRuntime.SetMarketTitle(__instance); } } }