using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TobaccoPotAndCigar.Compatibility; using TobaccoPotAndCigar.Prefabs; using TobaccoPotAndCigar.Runtime; using TobaccoPotAndCigar.Shops; using TobaccoPotAndCigar.Smoking; using UnityEngine; using UnityEngine.PostProcessing; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("TobaccoPotAndCigar")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TobaccoPotAndCigar")] [assembly: AssemblyTitle("TobaccoPotAndCigar")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 TobaccoPotAndCigar { [BepInPlugin("DogEggz.Cigar", "Tobacco pot and cigar", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "DogEggz.Cigar"; public const string PluginName = "Tobacco pot and cigar"; public const string PluginVersion = "1.0.0"; private Harmony harmony; internal static ManualLogSource LogSource { get; private set; } internal static string PluginDirectory { get; private set; } private void Awake() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown LogSource = ((BaseUnityPlugin)this).Logger; PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty; RuntimeDiagnostics.InfoSink = delegate(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); }; RuntimeDiagnostics.WarningSink = delegate(string message) { ((BaseUnityPlugin)this).Logger.LogWarning((object)message); }; RuntimeDiagnostics.ErrorSink = delegate(string message) { ((BaseUnityPlugin)this).Logger.LogError((object)message); }; CigarAssetBundle.Load(PluginDirectory); harmony = new Harmony("DogEggz.Cigar"); harmony.PatchAll(typeof(Plugin).Assembly); ShopPlacement.ResetDiagnostics(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Tobacco pot and cigar 1.0.0 loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } CigarEffectService.Reset(); RadRefinementsCompatibility.Reset(); CigarPrefabRegistrar.Reset(); CigarAssetBundle.Unload(); ShopPlacement.ResetDiagnostics(); RuntimeDiagnostics.Reset(); PluginDirectory = null; LogSource = null; } } } namespace TobaccoPotAndCigar.Smoking { internal static class CigarEffectService { private sealed class DoseChannel { internal CigarTobaccoType Type; internal float Charge; } private sealed class DoseGroup { internal readonly List Channels = new List(3); } private static readonly Dictionary Doses = new Dictionary(); private static readonly List RemovalBuffer = new List(); internal static void ApplyInhale(CigarRuntimeState source, TobaccoBlend blend, float deltaTime) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 if (!((Object)(object)source == (Object)null) && !(deltaTime <= 0f)) { DoseGroup orCreateDose = GetOrCreateDose(source, blend); BlueEffectProfile blueEffectProfile = RadRefinementsCompatibility.GetBlueEffectProfile(); CigarEffectTotals val = CigarEffectMath.Calculate(blend, blueEffectProfile.ImmediateSleepChange, blueEffectProfile.GreenVisualChargeRate); PlayerNeeds.sleep += deltaTime * val.ImmediateSleepPerSecond; for (int i = 0; i < orCreateDose.Channels.Count; i++) { DoseChannel doseChannel = orCreateDose.Channels[i]; float num = (((int)doseChannel.Type == 5) ? blueEffectProfile.GreenVisualChargeRate : 2f); doseChannel.Charge += deltaTime * num; } } } internal static void TickAndCompose(PlayerTobacco vanilla, float deltaTime) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected I4, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)vanilla == (Object)null || Doses.Count == 0 || deltaTime <= 0f) { return; } float num = vanilla.white; float num2 = vanilla.green; float num3 = vanilla.black; RemovalBuffer.Clear(); foreach (KeyValuePair dose in Doses) { bool flag = false; List channels = dose.Value.Channels; for (int i = 0; i < channels.Count; i++) { DoseChannel doseChannel = channels[i]; if (!(doseChannel.Charge <= 0f)) { flag = true; doseChannel.Charge = Mathf.Max(0f, doseChannel.Charge - deltaTime * 0.5f); CigarTobaccoType type = doseChannel.Type; switch (type - 1) { case 0: num += doseChannel.Charge; PlayerNeeds.sleep -= deltaTime * 0.165f; break; case 1: num2 += doseChannel.Charge; PlayerNeeds.sleep -= deltaTime * 0.055f; break; case 4: num2 += doseChannel.Charge; PlayerNeeds.sleep -= deltaTime * 0.055f; break; case 2: num3 += doseChannel.Charge; PlayerNeeds.sleep -= deltaTime * 0.3f; break; case 3: PlayerNeeds.sleep -= deltaTime * 0.2f; break; } } } if (!flag) { RemovalBuffer.Add(dose.Key); } } for (int j = 0; j < RemovalBuffer.Count; j++) { Doses.Remove(RemovalBuffer[j]); } PlayerTobacco.saturationOverride = 1f + (num2 - num) / 100f; if ((Object)(object)vanilla.postProcessing != (Object)null) { Settings settings = vanilla.postProcessing.bloom.settings; settings.bloom.intensity = Mathf.Lerp(0.66f, 0f, Mathf.Clamp01(num3 / 100f)); vanilla.postProcessing.bloom.settings = settings; } } internal static void Reset() { Doses.Clear(); RemovalBuffer.Clear(); CigarSmokeContext.Current = null; } private static DoseGroup GetOrCreateDose(CigarRuntimeState source, TobaccoBlend blend) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)source).GetInstanceID(); if (Doses.TryGetValue(instanceID, out var value)) { return value; } value = new DoseGroup(); AddChannels(value, (CigarTobaccoType)1, blend.White); AddChannels(value, (CigarTobaccoType)2, blend.Green); AddChannels(value, (CigarTobaccoType)3, blend.Black); AddChannels(value, (CigarTobaccoType)4, blend.Brown); AddChannels(value, (CigarTobaccoType)5, blend.Blue); Doses.Add(instanceID, value); return value; } private static void AddChannels(DoseGroup group, CigarTobaccoType type, int count) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < count; i++) { group.Channels.Add(new DoseChannel { Type = type }); } } } internal static class CigarSmokeContext { internal static CigarRuntimeState Current; } } namespace TobaccoPotAndCigar.Shops { internal static class ShopPlacement { private const string GoldRockScene = "island 1 A Gold Rock"; private const string DragonCliffsScene = "island 9 E Dragon Cliffs"; private const string SageHillsScene = "island 13 E (Sage Hills)"; private const string FortAestrinScene = "island 15 M (Fort)"; private static readonly HashSet LoggedIdentityFailures = new HashSet(); internal static void ResetDiagnostics() { LoggedIdentityFailures.Clear(); } internal static void ConfigureSpawnerBeforeStart(ShopItemSpawner spawner) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!CigarPrefabRegistrar.IsReady || (Object)(object)spawner == (Object)null) { return; } Scene scene = ((Component)spawner).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { return; } scene = ((Component)spawner).gameObject.scene; string name = ((Scene)(ref scene)).name; string name2 = ((Object)((Component)spawner).gameObject).name; if ((name == "island 1 A Gold Rock" && (name2 == "shop item (171)" || name2 == "shop item (173)")) || (name == "island 9 E Dragon Cliffs" && name2 == "shop item spawner (184)")) { if (!IsUniqueSpawner(spawner)) { LogIdentityFailure(name + "/" + name2); } else { spawner.itemPrefab = CigarAssetBundle.GetPrefab(613); } } } internal static void AddRelativeDisplaysAfterStart(ShopItemSpawner anchor) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) if (!CigarPrefabRegistrar.IsReady || (Object)(object)anchor == (Object)null) { return; } Scene scene = ((Component)anchor).gameObject.scene; if (((Scene)(ref scene)).IsValid() && IsUniqueSpawner(anchor)) { scene = ((Component)anchor).gameObject.scene; string name = ((Scene)(ref scene)).name; string name2 = ((Object)((Component)anchor).gameObject).name; if (name == "island 9 E Dragon Cliffs" && name2 == "shop item spawner (184)") { CreateRelativeSpawner(anchor, "DogEggz.Cigar.DriedLeaf.DragonCliffs.2", new Vector3(0.058f, 0.082f, -0.411f), new Vector3(8.804f, -13.728f, -7.962f), 613); Vector3 localPosition = ((Component)anchor).transform.localPosition; localPosition.y = 3.453f; ((Component)anchor).transform.localPosition = localPosition; ((Component)anchor).transform.localEulerAngles = new Vector3(90f, 28.584f, 0f); } else if (name == "island 15 M (Fort)" && name2 == "shop item (24)") { CreateRelativeSpawner(anchor, "DogEggz.Cigar.DriedLeaf.Fort.1", new Vector3(-0.734f, 0f, 0f), new Vector3(90f, 0f, 0f), 613); CreateRelativeSpawner(anchor, "DogEggz.Cigar.DriedLeaf.Fort.2", new Vector3(-0.734f, 0f, -0.367f), new Vector3(90f, 0f, 0f), 613); CreateRelativeSpawner(anchor, "DogEggz.Cigar.DriedLeaf.Fort.3", new Vector3(-0.734f, 0f, -0.734f), new Vector3(90f, 0f, 0f), 613); } } } internal static void AddSageHillsPotAfterStart(Shopkeeper shopkeeper) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if (!CigarPrefabRegistrar.IsReady || (Object)(object)shopkeeper == (Object)null) { return; } Scene scene = ((Component)shopkeeper).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { return; } scene = ((Component)shopkeeper).gameObject.scene; if (!(((Scene)(ref scene)).name != "island 13 E (Sage Hills)") && !(((Object)((Component)shopkeeper).gameObject).name != "shopkeeper (2)") && IsUniqueShopkeeper(shopkeeper)) { Transform val = FindDirectChild(((Component)shopkeeper).transform.parent, "shop area (3)"); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent() == (Object)null) { LogIdentityFailure("island 13 E (Sage Hills)/shopkeeper (2)+shop area (3)"); } else { CreateRelativeSpawner(((Component)shopkeeper).transform, availableAtNight: false, 1f, "DogEggz.Cigar.TobaccoPot.SageHills", new Vector3(-2.175f, 0.6f, 3.931f), Vector3.zero, 610); } } } private static void CreateRelativeSpawner(ShopItemSpawner anchor, string hostName, Vector3 localPosition, Vector3 localEuler, int prefabIndex) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) CreateRelativeSpawner(((Component)anchor).transform, anchor.availableAtNight, anchor.priceMult, hostName, localPosition, localEuler, prefabIndex); } private static void CreateRelativeSpawner(Transform anchor, bool availableAtNight, float priceMultiplier, string hostName, Vector3 localPosition, Vector3 localEuler, int prefabIndex) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Transform parent = anchor.parent; if (!((Object)(object)parent == (Object)null) && !((Object)(object)FindDirectChild(parent, hostName) != (Object)null)) { GameObject val = new GameObject(hostName) { layer = ((Component)anchor).gameObject.layer }; val.transform.SetParent(parent, true); val.transform.position = anchor.TransformPoint(localPosition); val.transform.rotation = anchor.rotation * Quaternion.Euler(localEuler); val.transform.localScale = Vector3.one; val.AddComponent(); val.AddComponent(); ShopItemSpawner obj = val.AddComponent(); obj.itemPrefab = CigarAssetBundle.GetPrefab(prefabIndex); obj.availableAtNight = availableAtNight; obj.priceMult = priceMultiplier; ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { string[] obj2 = new string[5] { "Added shop display ", hostName, " in ", null, null }; Scene scene = ((Component)anchor).gameObject.scene; obj2[3] = ((Scene)(ref scene)).name; obj2[4] = "."; logSource.LogInfo((object)string.Concat(obj2)); } } } private static bool IsUniqueSpawner(ShopItemSpawner target) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) int num = 0; ShopItemSpawner[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] != (Object)null)) { continue; } Scene scene = ((Component)array[i]).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { scene = ((Component)array[i]).gameObject.scene; int handle = ((Scene)(ref scene)).handle; scene = ((Component)target).gameObject.scene; if (handle == ((Scene)(ref scene)).handle && ((Object)((Component)array[i]).gameObject).name == ((Object)((Component)target).gameObject).name) { num++; } } } return num == 1; } private static bool IsUniqueShopkeeper(Shopkeeper target) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) int num = 0; Shopkeeper[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] != (Object)null)) { continue; } Scene scene = ((Component)array[i]).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { scene = ((Component)array[i]).gameObject.scene; int handle = ((Scene)(ref scene)).handle; scene = ((Component)target).gameObject.scene; if (handle == ((Scene)(ref scene)).handle && ((Object)((Component)array[i]).gameObject).name == ((Object)((Component)target).gameObject).name) { num++; } } } return num == 1; } private static Transform FindDirectChild(Transform parent, string name) { if ((Object)(object)parent == (Object)null) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (((Object)child).name == name) { return child; } } return null; } private static void LogIdentityFailure(string identity) { if (LoggedIdentityFailures.Add(identity)) { ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { logSource.LogError((object)("Shop placement identity did not resolve exactly once: " + identity + ". That display was skipped.")); } } } } } namespace TobaccoPotAndCigar.Prefabs { internal static class CigarAssetBundle { internal const string BundleName = "dogeggz.cigar.assets"; private static readonly Dictionary Prefabs = new Dictionary(); private static AssetBundle bundle; internal static bool IsLoaded { get { if ((Object)(object)bundle != (Object)null) { return Prefabs.Count == 4; } return false; } } internal static void Load(string pluginDirectory) { if (IsLoaded) { return; } string text = Path.Combine(pluginDirectory, "assets", "dogeggz.cigar.assets"); if (!File.Exists(text)) { throw new FileNotFoundException("Cigar AssetBundle is missing.", text); } bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)bundle == (Object)null) { throw new InvalidOperationException("Unity could not load " + text); } Prefabs.Clear(); GameObject[] array = bundle.LoadAllAssets(); for (int i = 0; i < array.Length; i++) { SaveablePrefab component = array[i].GetComponent(); if ((Object)(object)component == (Object)null) { continue; } int prefabIndex = component.prefabIndex; if (prefabIndex >= 610 && prefabIndex <= 613) { if (Prefabs.ContainsKey(prefabIndex)) { throw new InvalidOperationException("AssetBundle contains duplicate prefab index " + prefabIndex + "."); } Prefabs.Add(prefabIndex, array[i]); } } for (int j = 610; j <= 613; j++) { if (!Prefabs.ContainsKey(j)) { throw new InvalidOperationException("AssetBundle is missing prefab index " + j + "."); } } } internal static GameObject GetPrefab(int index) { if (!Prefabs.TryGetValue(index, out var value)) { return null; } return value; } internal static void Unload() { Prefabs.Clear(); if ((Object)(object)bundle != (Object)null) { bundle.Unload(false); } bundle = null; } } internal static class CigarPrefabRegistrar { private const int RequiredDirectoryLength = 614; private static bool registered; internal static bool IsReady => registered; internal static void EnsureRegistered(PrefabsDirectory directory) { if (registered) { return; } if ((Object)(object)directory == (Object)null || directory.directory == null) { throw new InvalidOperationException("PrefabsDirectory is unavailable."); } if (!CigarAssetBundle.IsLoaded) { throw new InvalidOperationException("Cigar AssetBundle is not loaded."); } GameObject[] array = directory.directory; if (array.Length < 614) { Array.Resize(ref array, 614); } for (int i = 610; i <= 613; i++) { GameObject prefab = CigarAssetBundle.GetPrefab(i); GameObject val = array[i]; if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)prefab) { throw new InvalidOperationException("Prefab index " + i + " is already occupied by " + ((Object)val).name + "; registration aborted without overwriting it."); } ValidateBundledPrefab(i, prefab); } directory.directory = array; for (int j = 610; j <= 613; j++) { GameObject prefab2 = CigarAssetBundle.GetPrefab(j); directory.directory[j] = prefab2; PrefabReplacement.RegisterCustomPrefab(j, prefab2); } registered = true; } internal static void ValidateAndConfigure(PrefabsDirectory directory) { if (!registered || (Object)(object)directory == (Object)null || directory.shipItems == null || directory.shipItems.Length < 614) { throw new InvalidOperationException("PrefabsDirectory ship-item cache was not populated for indices 610-613."); } for (int i = 610; i <= 613; i++) { if ((Object)(object)directory.directory[i] != (Object)(object)CigarAssetBundle.GetPrefab(i) || (Object)(object)directory.shipItems[i] == (Object)null) { throw new InvalidOperationException("Runtime prefab cache validation failed at index " + i + "."); } } for (int j = 300; j <= 302; j++) { VanillaPipeSmokeProfile.ApplyRequired(directory.directory[j], j); } ConfigureTobaccoHint(directory.directory[310], 310); ConfigureTobaccoHint(directory.directory[312], 312); ConfigureTobaccoHint(directory.directory[314], 314); ConfigureTobaccoHint(directory.directory[316], 316); ConfigureTobaccoHint(directory.directory[318], 318); ConfigureVanillaDrying(directory.directory[312], 310); ConfigureVanillaDrying(directory.directory[310], 316); ConfigureVanillaDrying(directory.directory[316], 314); ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { logSource.LogInfo((object)"Registered bundled prefabs 610-613 and rack-only tobacco drying."); } } internal static void Reset() { registered = false; PrefabReplacement.ClearCustomPrefabs(); } private static void ConfigureVanillaDrying(GameObject prefab, int resultPrefabIndex) { if ((Object)(object)prefab == (Object)null) { throw new InvalidOperationException("Vanilla drying source for result " + resultPrefabIndex + " is missing."); } RackOnlyDrying val = prefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent(); } val.ConfigureResultPrefab(resultPrefabIndex); } private static void ConfigureTobaccoHint(GameObject prefab, int prefabIndex) { ShipItemTobacco val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent() : null); if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(((ShipItem)val).name)) { throw new InvalidOperationException("Tobacco prefab " + prefabIndex + " cannot provide its pointer hint name."); } ((GoPointerButton)val).description = ((ShipItem)val).name; } private static void ValidateBundledPrefab(int index, GameObject prefab) { if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent() == (Object)null || (Object)(object)prefab.GetComponent() == (Object)null) { throw new InvalidOperationException("Bundled prefab " + index + " is missing its item/save contract."); } int num; if (index != 610) { if (index != 611) { num = (((index == 612) ? ((Object)(object)prefab.GetComponent() != (Object)null) : ((Object)(object)prefab.GetComponent() != (Object)null)) ? 1 : 0); } else { if (!((Object)(object)prefab.GetComponent() != (Object)null)) { goto IL_00a2; } num = (((Object)(object)prefab.GetComponent() != (Object)null) ? 1 : 0); } } else { num = (((Object)(object)prefab.GetComponent() != (Object)null) ? 1 : 0); } if (num != 0) { return; } goto IL_00a2; IL_00a2: throw new InvalidOperationException("Bundled prefab " + index + " does not contain its authored runtime component."); } } internal static class VanillaPipeSmokeProfile { internal const float EmissionRate = 300f; internal const float MaximumLifetime = 20f; internal const int MaximumParticles = 5000; internal static void ApplyRequired(GameObject prefab, int prefabIndex) { if ((Object)(object)prefab == (Object)null) { throw new InvalidOperationException("Vanilla pipe prefab " + prefabIndex + " is missing."); } SaveablePrefab component = prefab.GetComponent(); ShipItemPipe component2 = prefab.GetComponent(); if ((Object)(object)component == (Object)null || component.prefabIndex != prefabIndex || (Object)(object)component2 == (Object)null || !Apply(component2)) { throw new InvalidOperationException("Vanilla pipe prefab " + prefabIndex + " does not expose its expected smoke profile."); } } internal static bool ApplyIfVanilla(ShipItemPipe pipe) { if ((Object)(object)pipe == (Object)null) { return false; } SaveablePrefab component = ((Component)pipe).GetComponent(); if ((Object)(object)component == (Object)null || component.prefabIndex < 300 || component.prefabIndex > 302) { return false; } return Apply(pipe); } private static bool Apply(ShipItemPipe pipe) { //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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) ParticleSystem componentInChildren = ((Component)pipe).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return false; } pipe.maxLifetime = 20f; pipe.maxEmission = 300f; MainModule main = componentInChildren.main; ((MainModule)(ref main)).maxParticles = 5000; EmissionModule emission = componentInChildren.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(300f); return true; } } } namespace TobaccoPotAndCigar.Patches { [HarmonyPatch(typeof(ShipItem), "OnItemClick")] internal static class CustomItemClickPatch { [HarmonyPrefix] private static bool Prefix(ShipItem __instance, PickupableItem heldItem, ref bool __result) { TobaccoPlantPotState component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null) { __result = false; if ((Object)(object)heldItem != (Object)null) { component.TryAcceptWater(((Component)heldItem).GetComponent()); } return false; } DriedTobaccoLeafState component2 = ((Component)__instance).GetComponent(); if ((Object)(object)component2 != (Object)null) { __result = false; if ((Object)(object)heldItem != (Object)null) { component2.TryInsert(((Component)heldItem).GetComponent()); } return false; } return true; } } [HarmonyPatch(typeof(ShipItem), "OnAltActivate")] internal static class CustomAltInteractionPatch { [HarmonyPrefix] private static bool Prefix(ShipItem __instance) { TobaccoPlantPotState component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && __instance.sold) { component.TryHarvest(); return false; } DriedTobaccoLeafState component2 = ((Component)__instance).GetComponent(); if ((Object)(object)component2 != (Object)null && __instance.sold) { component2.TryRoll(); return false; } return true; } } [HarmonyPatch(typeof(ShipItemBottle), "AllowOnItemClick")] internal static class PotWaterTargetPatch { [HarmonyPostfix] private static void Postfix(ShipItemBottle __instance, GoPointerButton lookedAtButton, ref bool __result) { if (!__result && !((Object)(object)lookedAtButton == (Object)null) && ((ShipItem)__instance).sold) { TobaccoPlantPotState component = ((Component)lookedAtButton).GetComponent(); if ((Object)(object)component != (Object)null && component.StoredWater < 15f && (Object)(object)((Component)lookedAtButton).GetComponent() != (Object)null && ((Component)lookedAtButton).GetComponent().sold && ((ShipItem)__instance).amount == 1f && ((ShipItem)__instance).health > 0f) { __result = true; } } } } [HarmonyPatch(typeof(ShipItemTobacco), "AllowOnItemClick")] internal static class TobaccoTargetPatch { [HarmonyPostfix] private static void Postfix(ShipItemTobacco __instance, GoPointerButton lookedAtButton, ref bool __result) { if ((Object)(object)lookedAtButton == (Object)null) { return; } if ((Object)(object)((Component)lookedAtButton).GetComponent() != (Object)null) { __result = false; return; } DriedTobaccoLeafState component = ((Component)lookedAtButton).GetComponent(); ShipItem component2 = ((Component)lookedAtButton).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null && component2.sold && ((ShipItem)__instance).sold && component.FillCount < 3) { __result = true; } } } [HarmonyPatch(typeof(ShipItemKnife), "AllowOnItemClick")] internal static class TobaccoLeafKnifeTargetPatch { [HarmonyPostfix] private static void Postfix(ShipItemKnife __instance, GoPointerButton lookedAtButton, ref bool __result) { if (!__result && ((ShipItem)__instance).sold && (Object)(object)lookedAtButton != (Object)null) { ShipItem component = ((Component)lookedAtButton).GetComponent(); __result = (Object)(object)component != (Object)null && component.sold && (Object)(object)((Component)component).GetComponent() != (Object)null; } } } [HarmonyPatch(typeof(ShipItemKnife), "OnAltActivate")] internal static class TobaccoLeafKnifePatch { private const int SliceCount = 3; [HarmonyPostfix] private static void Postfix(ShipItemKnife __instance, ref bool ___animating, ref float ___heldRotationOffset, ref float ___cutTimer) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!((ShipItem)__instance).sold || (Object)(object)((PickupableItem)__instance).held == (Object)null) { return; } ShipItem pointedAtItem = ((PickupableItem)__instance).held.GetPointedAtItem(); if ((Object)(object)pointedAtItem == (Object)null || !pointedAtItem.sold || (Object)(object)((Component)pointedAtItem).GetComponent() == (Object)null || !PrefabReplacement.CanSpawn(312)) { return; } ___animating = true; ___heldRotationOffset = 0f; ___cutTimer = 0.25f; List list = new List(3); float num = -0.03f; for (int i = 0; i < 3; i++) { ShipItem val = PrefabReplacement.SpawnOwned(312, ((Component)pointedAtItem).transform.position + ((Component)pointedAtItem).transform.right * num, ((Component)pointedAtItem).transform.rotation * Quaternion.Euler(0f, 90f, 0f), pointedAtItem, 0f, 0f); if ((Object)(object)val != (Object)null) { list.Add(val); } num += 0.02f; } if (list.Count == 3) { pointedAtItem.DestroyItem(); return; } for (int j = 0; j < list.Count; j++) { list[j].DestroyItem(); } RuntimeDiagnostics.Error("Knife cut could not create all three green tobaccos; partial output was rolled back and the leaf was preserved."); } } [HarmonyPatch(typeof(ShipItemPipe), "OnItemClick")] internal static class CigarRefillBlockPatch { [HarmonyPrefix] private static bool Prefix(ShipItemPipe __instance, ref bool __result) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ShipItemPipe), "ExtraLateUpdate")] internal static class CigarPipeContextPatch { [HarmonyPrefix] private static void Prefix(ShipItemPipe __instance, out CigarRuntimeState __state) { __state = ((Component)__instance).GetComponent(); CigarSmokeContext.Current = __state; } [HarmonyPostfix] private static void Postfix(CigarRuntimeState __state, float ___currentHeat, bool ___inhaling) { if ((Object)(object)__state != (Object)null && !__state.TryDestroyIfConsumed()) { __state.SyncVisuals(false, ___currentHeat / 100f, ___inhaling); } if ((Object)(object)CigarSmokeContext.Current == (Object)(object)__state) { CigarSmokeContext.Current = null; } } } [HarmonyPatch(typeof(ShipItemPipe), "OnLoad")] internal static class CigarPipeLoadPatch { [HarmonyPostfix] private static void Postfix(ShipItemPipe __instance) { VanillaPipeSmokeProfile.ApplyIfVanilla(__instance); CigarRuntimeState component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && !component.TryDestroyIfConsumed()) { component.RefreshValue(); component.SyncVisuals(true, 0f, false); } } } [HarmonyPatch(typeof(PrefabsDirectory), "Start")] internal static class PrefabRegistrationPatches { [HarmonyPrefix] [HarmonyPriority(0)] private static void Prefix(PrefabsDirectory __instance) { CigarPrefabRegistrar.EnsureRegistered(__instance); } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(PrefabsDirectory __instance) { CigarPrefabRegistrar.ValidateAndConfigure(__instance); } } [HarmonyPatch(typeof(SaveablePrefab), "Load")] internal static class SaveLoadSyncPatches { [HarmonyPostfix] private static void Postfix(SaveablePrefab __instance) { RuntimeStateSynchronizer.Sync(((Component)__instance).GetComponent(), true); } } [HarmonyPatch(typeof(ShopItemSpawner), "Start")] internal static class ShopItemSpawnerPlacementPatch { [HarmonyPrefix] private static void Prefix(ShopItemSpawner __instance) { ShopPlacement.ConfigureSpawnerBeforeStart(__instance); } [HarmonyPostfix] private static void Postfix(ShopItemSpawner __instance) { ShopPlacement.AddRelativeDisplaysAfterStart(__instance); } } [HarmonyPatch(typeof(Shopkeeper), "Start")] internal static class SageHillsPotPlacementPatch { [HarmonyPostfix] private static void Postfix(Shopkeeper __instance) { ShopPlacement.AddSageHillsPotAfterStart(__instance); } } [HarmonyPatch(typeof(PlayerTobacco), "Smoke")] internal static class CigarSmokeRecipePatch { [HarmonyPrefix] private static bool Prefix(int tobaccoType) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (tobaccoType >= 0) { return true; } CigarRuntimeState current = CigarSmokeContext.Current; TobaccoBlend blend = default(TobaccoBlend); if ((Object)(object)current == (Object)null || !TobaccoBlendCodec.TryDecode(-tobaccoType, ref blend)) { RuntimeDiagnostics.Error("Rejected a cigar smoke call with no valid cigar recipe context."); return false; } CigarEffectService.ApplyInhale(current, blend, Time.deltaTime); return false; } } [HarmonyPatch(typeof(PlayerTobacco), "Update")] internal static class CigarEffectUpdatePatch { [HarmonyPostfix] private static void Postfix(PlayerTobacco __instance) { CigarEffectService.TickAndCompose(__instance, Time.deltaTime); } } } namespace TobaccoPotAndCigar.Compatibility { internal struct BlueEffectProfile { internal float ImmediateSleepChange; internal float GreenVisualChargeRate; internal static BlueEffectProfile VanillaGreen => new BlueEffectProfile { ImmediateSleepChange = -0.11f, GreenVisualChargeRate = 2f }; internal static BlueEffectProfile RadEnhanced(int multiplier) { multiplier = Math.Max(0, multiplier); return new BlueEffectProfile { ImmediateSleepChange = -0.11f * (float)multiplier, GreenVisualChargeRate = 2f * (float)multiplier * 0.33f }; } } internal static class RadRefinementsCompatibility { internal const string PluginGuid = "com.raddude.radrefinements"; private static ConfigEntry enableBlueTobacco; private static ConfigEntry bluePotencyMult; private static bool warnedAboutIncompatibleVersion; internal static BlueEffectProfile GetBlueEffectProfile() { if (!Chainloader.PluginInfos.TryGetValue("com.raddude.radrefinements", out var value)) { return BlueEffectProfile.VanillaGreen; } if ((enableBlueTobacco == null || bluePotencyMult == null) && !TryBindConfigEntries(((object)value.Instance).GetType().Assembly)) { WarnOnce(); return BlueEffectProfile.VanillaGreen; } if (!enableBlueTobacco.Value) { return BlueEffectProfile.VanillaGreen; } return BlueEffectProfile.RadEnhanced(bluePotencyMult.Value); } internal static void Reset() { enableBlueTobacco = null; bluePotencyMult = null; warnedAboutIncompatibleVersion = false; } private static bool TryBindConfigEntries(Assembly assembly) { Type type = assembly.GetType("RadRefinements.Configs", throwOnError: false); if (type == null) { return false; } FieldInfo field = type.GetField("enableBlueTobacco", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("bluePotencyMult", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); enableBlueTobacco = ((field == null) ? null : (field.GetValue(null) as ConfigEntry)); bluePotencyMult = ((field2 == null) ? null : (field2.GetValue(null) as ConfigEntry)); if (enableBlueTobacco != null) { return bluePotencyMult != null; } return false; } private static void WarnOnce() { if (!warnedAboutIncompatibleVersion) { warnedAboutIncompatibleVersion = true; ManualLogSource logSource = Plugin.LogSource; if (logSource != null) { logSource.LogWarning((object)"Rad Refinements was detected but its blue-tobacco settings could not be read. Cigar blue tobacco will use vanilla green effects."); } } } } }