using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; using UnityEngine; [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.Runtime")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TobaccoPotAndCigar.Runtime")] [assembly: AssemblyTitle("TobaccoPotAndCigar.Runtime")] [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.Runtime { public struct CigarEffectTotals { public float ImmediateSleepPerSecond; public float LingeringSleepPerSecond; public float WhiteVisualInputPerSecond; public float GreenVisualInputPerSecond; public float BlackVisualInputPerSecond; } public static class CigarEffectMath { public static CigarEffectTotals Calculate(TobaccoBlend blend, float blueImmediateSleepPerSecond, float blueGreenVisualInputPerSecond) { return new CigarEffectTotals { ImmediateSleepPerSecond = (float)blend.White * 0.66f - (float)blend.Green * 0.11f + (float)blend.Blue * blueImmediateSleepPerSecond + (float)blend.Black * 1.2f + (float)blend.Brown * 0.8f, LingeringSleepPerSecond = (float)blend.White * -0.165f + (float)blend.Green * -0.055f + (float)blend.Blue * -0.055f + (float)blend.Black * -0.3f + (float)blend.Brown * -0.2f, WhiteVisualInputPerSecond = (float)blend.White * 2f, GreenVisualInputPerSecond = (float)blend.Green * 2f + (float)blend.Blue * blueGreenVisualInputPerSecond, BlackVisualInputPerSecond = (float)blend.Black * 2f }; } } public enum CigarEmberCoolingPhase { Dark, YellowToOrange, OrangeToRed, RedToDark } public static class CigarEmberMath { private const float BoundaryEpsilon = 0.0001f; public const float YellowToOrangeSeconds = 2f; public const float OrangeToRedSeconds = 12f; public const float RedToDarkSeconds = 36f; public const float FullHeatCoolingSeconds = 50f; public static CigarEmberCoolingPhase GetCoolingPhase(float currentHeat01, float coolingStartHeat01) { if (currentHeat01 <= 0f || coolingStartHeat01 <= 0f) { return CigarEmberCoolingPhase.Dark; } float profileSeconds = GetProfileSeconds(currentHeat01, coolingStartHeat01); if (profileSeconds + 0.0001f < 2f) { return CigarEmberCoolingPhase.YellowToOrange; } if (profileSeconds + 0.0001f < 14f) { return CigarEmberCoolingPhase.OrangeToRed; } return CigarEmberCoolingPhase.RedToDark; } public static float GetPhaseProgress(CigarEmberCoolingPhase phase, float currentHeat01, float coolingStartHeat01) { if (currentHeat01 <= 0f || coolingStartHeat01 <= 0f) { if (phase != CigarEmberCoolingPhase.RedToDark) { return 0f; } return 1f; } float profileSeconds = GetProfileSeconds(currentHeat01, coolingStartHeat01); return phase switch { CigarEmberCoolingPhase.YellowToOrange => Mathf.Clamp01(profileSeconds / 2f), CigarEmberCoolingPhase.OrangeToRed => Mathf.Clamp01((profileSeconds - 2f) / 12f), CigarEmberCoolingPhase.RedToDark => Mathf.Clamp01((profileSeconds - 2f - 12f) / 36f), _ => 0f, }; } public static float GetProfileSeconds(float currentHeat01, float coolingStartHeat01) { if (coolingStartHeat01 <= 0f) { return 50f; } float num = Mathf.Clamp01(currentHeat01 / coolingStartHeat01); return (1f - num) * 50f; } } public static class CigarHintText { public const string GreenHex = "3FAF45"; public const string BrownHex = "8B5A2B"; public const string BlueHex = "3F7FFF"; public const string BlackHex = "202020"; public static string Build(TobaccoRecipe recipe) { if (recipe.Count <= 0) { return "cigar"; } if (recipe.IsFullSingleType) { return "Full " + GetName(recipe.GetAt(0)) + " Cigar"; } string text = ""; for (int i = 0; i < recipe.Count; i++) { text += GetColoredLetter(recipe.GetAt(i)); } return text + " Cigar"; } private static string GetName(CigarTobaccoType tobaccoType) { return tobaccoType switch { CigarTobaccoType.White => "White", CigarTobaccoType.Green => "Green", CigarTobaccoType.Black => "Black", CigarTobaccoType.Brown => "Brown", CigarTobaccoType.Blue => "Blue", _ => "Unknown", }; } private static string GetColoredLetter(CigarTobaccoType tobaccoType) { return tobaccoType switch { CigarTobaccoType.White => "W", CigarTobaccoType.Green => Color("G", "3FAF45"), CigarTobaccoType.Brown => Color("B", "8B5A2B"), CigarTobaccoType.Blue => Color("B", "3F7FFF"), CigarTobaccoType.Black => Color("B", "202020"), _ => "?", }; } private static string Color(string letter, string hex) { return "" + letter + ""; } } public static class CigarValueMath { public const int WrapperValue = 200; public static int Calculate(TobaccoBlend blend, int whiteValue, int greenValue, int blackValue, int brownValue, int blueValue) { return 200 + blend.White * whiteValue + blend.Green * greenValue + blend.Black * blackValue + blend.Brown * brownValue + blend.Blue * blueValue; } public static int ScaleByRemainingHealth(int fullValue, float currentHealth, float initialHealth) { if (fullValue <= 0) { return 0; } if (initialHealth <= 0f || float.IsNaN(initialHealth)) { return fullValue; } if (currentHealth <= 0f || float.IsNaN(currentHealth)) { return 0; } if (currentHealth >= initialHealth) { return fullValue; } double value = (double)fullValue * (double)currentHealth / (double)initialHealth; return Math.Max(0, (int)Math.Round(value, MidpointRounding.AwayFromZero)); } } public sealed class CigarRuntimeState : MonoBehaviour { [SerializeField] private CigarVisualController cigarVisual; private ShipItemPipe pipe; private int fullRecipeValue; private bool valueInitialized; private bool destructionQueued; public ShipItemPipe Pipe => pipe; private void Awake() { pipe = ((Component)this).GetComponent(); if ((Object)(object)cigarVisual == (Object)null) { cigarVisual = ((Component)this).GetComponentInChildren(true); } if ((Object)(object)cigarVisual != (Object)null) { cigarVisual.BindRoot(pipe); } } private void Start() { RefreshValue(); SyncVisuals(snap: true, 0f, inhaling: false); } public bool TryGetBlend(out TobaccoBlend blend) { blend = default(TobaccoBlend); if (!TryGetRecipe(out var recipe)) { return false; } blend = recipe.ToBlend(); return true; } public bool TryGetRecipe(out TobaccoRecipe recipe) { recipe = default(TobaccoRecipe); bool wasLegacy; if ((Object)(object)pipe != (Object)null) { return TobaccoRecipeCodec.TryDecodeCigar(((ShipItem)pipe).amount, out recipe, out wasLegacy); } return false; } public float GetInitialHealth() { if (!TryGetRecipe(out var recipe)) { return 0f; } return (float)recipe.Count * 100f; } public void SyncVisuals(bool snap, float heat01, bool inhaling) { if ((Object)(object)pipe == (Object)null) { pipe = ((Component)this).GetComponent(); } if (!((Object)(object)pipe == (Object)null)) { float initialHealth = GetInitialHealth(); SyncValueFromHealth(initialHealth); if (!((Object)(object)cigarVisual == (Object)null)) { float remaining = ((initialHealth > 0f) ? Mathf.Clamp01(((ShipItem)pipe).health / initialHealth) : 0f); cigarVisual.SetRemaining01(remaining, ((ShipItem)pipe).health > 0f && initialHealth > 0f, Mathf.Clamp01(heat01), inhaling, snap); } } } public void RefreshValue() { if ((Object)(object)pipe == (Object)null) { pipe = ((Component)this).GetComponent(); } if (!((Object)(object)pipe == (Object)null)) { if (!TryGetRecipe(out var recipe)) { fullRecipeValue = 200; valueInitialized = true; ((GoPointerButton)pipe).description = "cigar"; SyncValueFromHealth(0f); } else { TobaccoBlend blend = recipe.ToBlend(); fullRecipeValue = CigarValueMath.Calculate(blend, GetPrefabValue(310), GetPrefabValue(312), GetPrefabValue(314), GetPrefabValue(316), GetPrefabValue(318)); valueInitialized = true; ((GoPointerButton)pipe).description = CigarHintText.Build(recipe); SyncValueFromHealth((float)blend.Count * 100f); } } } public bool TryDestroyIfConsumed() { if (destructionQueued) { return true; } if ((Object)(object)pipe == (Object)null) { pipe = ((Component)this).GetComponent(); } if ((Object)(object)pipe == (Object)null || ((ShipItem)pipe).health > 0f) { return false; } destructionQueued = true; ((ShipItem)pipe).DestroyItem(); return true; } private void SyncValueFromHealth(float initialHealth) { if (valueInitialized && !((Object)(object)pipe == (Object)null)) { int num = CigarValueMath.ScaleByRemainingHealth(fullRecipeValue, ((ShipItem)pipe).health, initialHealth); if (((ShipItem)pipe).value != num) { ((ShipItem)pipe).value = num; } } } private static int GetPrefabValue(int prefabIndex) { PrefabsDirectory instance = PrefabsDirectory.instance; if ((Object)(object)instance == (Object)null || instance.directory == null || prefabIndex < 0 || prefabIndex >= instance.directory.Length || (Object)(object)instance.directory[prefabIndex] == (Object)null) { return 0; } ShipItem component = instance.directory[prefabIndex].GetComponent(); if (!((Object)(object)component != (Object)null)) { return 0; } return component.value; } } public sealed class CigarVisualController : MonoBehaviour { private const float BurnVisualLerpSpeed = 12f; private const float SpentFrontClearance = 0.008f; private const float MinimumPhysicalColliderRatio = 0.05f; private const float MinimumPickupLength = 0.04f; private const float MaximumEmberLightIntensity = 0.15f; private const int IgnoreRaycastLayer = 2; private static readonly int ColorProperty = Shader.PropertyToID("_Color"); private static readonly int EmissionColorProperty = Shader.PropertyToID("_EmissionColor"); private static readonly Color YellowColor = new Color(1f, 0.42f, 0.025f, 1f); private static readonly Color OrangeColor = new Color(0.92f, 0.12f, 0.008f, 1f); private static readonly Color YellowEmission = new Color(3.2f, 0.85f, 0.04f, 1f); private static readonly Color OrangeEmission = new Color(2.6f, 0.22f, 0.012f, 1f); private static readonly Color YellowLightColor = new Color(1f, 0.38f, 0.04f, 1f); private static readonly Color OrangeLightColor = new Color(1f, 0.12f, 0.015f, 1f); private static readonly Color RedLightColor = new Color(1f, 0.025f, 0.008f, 1f); [SerializeField] private Transform mouthAnchor; [SerializeField] private Transform burnableBody; [SerializeField] private Transform burnFront; [SerializeField] private GameObject band; [SerializeField] private Renderer emberRenderer; [SerializeField] private Light emberLight; [SerializeField] private BoxCollider rootCollider; [SerializeField] private BoxCollider pickupCollider; [SerializeField] private Collider mouthSmokingTrigger; private ShipItemPipe pipe; private BoxCollider physicalCollider; private Vector3 fullBodyScale; private Vector3 fullBurnFrontPosition; private Vector3 spentBurnFrontPosition; private Vector3 fullRootColliderCenter; private Vector3 fullRootColliderSize; private Vector3 fullPickupColliderCenter; private Vector3 fullPickupColliderSize; private float rootColliderMouthEndY; private float pickupColliderMouthEndY; private float burnDirectionSign; private float bandThresholdY; private float targetRemaining01; private float visibleRemaining01; private float heat01; private float coolingStartHeat01; private bool inhaling; private bool wasInhaling; private bool hasCoolingStartHeat; private bool available; private bool initialized; private MaterialPropertyBlock emberProperties; private Color emberBaseColor = Color.white; private Color emberBaseEmission = Color.black; private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0035: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_019b: 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) fullBodyScale = (((Object)(object)burnableBody != (Object)null) ? burnableBody.localScale : Vector3.one); fullBurnFrontPosition = (((Object)(object)burnFront != (Object)null) ? burnFront.localPosition : Vector3.zero); burnDirectionSign = (((Object)(object)mouthAnchor != (Object)null && (Object)(object)burnFront != (Object)null) ? Mathf.Sign(burnFront.localPosition.y - mouthAnchor.localPosition.y) : 1f); if (Mathf.Approximately(burnDirectionSign, 0f)) { burnDirectionSign = 1f; } spentBurnFrontPosition = fullBurnFrontPosition; if ((Object)(object)mouthAnchor != (Object)null) { spentBurnFrontPosition.y = mouthAnchor.localPosition.y + burnDirectionSign * 0.008f; } bandThresholdY = (((Object)(object)band != (Object)null) ? band.transform.localPosition.y : spentBurnFrontPosition.y); CacheRootColliderGeometry(); CachePickupColliderGeometry(); if ((Object)(object)emberRenderer != (Object)null && (Object)(object)emberRenderer.sharedMaterial != (Object)null) { Material sharedMaterial = emberRenderer.sharedMaterial; if (sharedMaterial.HasProperty(ColorProperty)) { emberBaseColor = sharedMaterial.GetColor(ColorProperty); } if (sharedMaterial.HasProperty(EmissionColorProperty)) { emberBaseEmission = sharedMaterial.GetColor(EmissionColorProperty); } emberProperties = new MaterialPropertyBlock(); } } public void BindRoot(ShipItemPipe newPipe) { pipe = newPipe; SyncInteractionLayers(); if ((Object)(object)rootCollider == (Object)null && (Object)(object)pipe != (Object)null) { rootCollider = ((Component)pipe).GetComponent(); CacheRootColliderGeometry(); } CachePickupColliderGeometry(); } public void SetRemaining01(float remaining, bool isAvailable, float newHeat01, bool isInhaling, bool snap) { targetRemaining01 = Mathf.Clamp01(remaining); available = isAvailable; heat01 = Mathf.Clamp01(newHeat01); UpdateInhaleState(isInhaling, snap); if (!available) { ResetEmberTimeline(); } if (!initialized || snap) { visibleRemaining01 = targetRemaining01; initialized = true; ApplyVisualState(); } } private void LateUpdate() { SyncInteractionLayers(); if (initialized) { TryBindPhysicalCollider(); float num = 1f - Mathf.Exp(-12f * Time.deltaTime); visibleRemaining01 = Mathf.Lerp(visibleRemaining01, targetRemaining01, num); if (Mathf.Abs(visibleRemaining01 - targetRemaining01) < 0.0001f) { visibleRemaining01 = targetRemaining01; } ApplyVisualState(); } } private void UpdateInhaleState(bool newInhaling, bool snap) { inhaling = newInhaling; if (snap) { wasInhaling = newInhaling; hasCoolingStartHeat = false; coolingStartHeat01 = 0f; } else if (newInhaling) { wasInhaling = true; hasCoolingStartHeat = false; coolingStartHeat01 = 0f; } else if (wasInhaling) { wasInhaling = false; coolingStartHeat01 = heat01; hasCoolingStartHeat = coolingStartHeat01 > 0f; } } private void ResetEmberTimeline() { inhaling = false; wasInhaling = false; coolingStartHeat01 = 0f; hasCoolingStartHeat = false; } private void SyncInteractionLayers() { if ((Object)(object)mouthSmokingTrigger != (Object)null && ((Component)mouthSmokingTrigger).gameObject.layer != 2) { ((Component)mouthSmokingTrigger).gameObject.layer = 2; } } private void TryBindPhysicalCollider() { if (!((Object)(object)physicalCollider != (Object)null) && !((Object)(object)pipe == (Object)null) && !((Object)(object)((ShipItem)pipe).itemRigidbodyC == (Object)null)) { physicalCollider = ((Component)((ShipItem)pipe).itemRigidbodyC).GetComponent(); } } private void CacheRootColliderGeometry() { //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_0027: 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) if (!((Object)(object)rootCollider == (Object)null)) { fullRootColliderCenter = rootCollider.center; fullRootColliderSize = rootCollider.size; rootColliderMouthEndY = fullRootColliderCenter.y - burnDirectionSign * fullRootColliderSize.y * 0.5f; } } private void CachePickupColliderGeometry() { //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_0027: 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) if (!((Object)(object)pickupCollider == (Object)null)) { fullPickupColliderCenter = pickupCollider.center; fullPickupColliderSize = pickupCollider.size; pickupColliderMouthEndY = fullPickupColliderCenter.y - burnDirectionSign * fullPickupColliderSize.y * 0.5f; } } private void ApplyVisualState() { //IL_000f: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)burnableBody != (Object)null) { Vector3 localScale = fullBodyScale; localScale.y = fullBodyScale.y * visibleRemaining01; burnableBody.localScale = localScale; } if ((Object)(object)burnFront != (Object)null) { burnFront.localPosition = Vector3.Lerp(spentBurnFrontPosition, fullBurnFrontPosition, visibleRemaining01); ((Component)burnFront).gameObject.SetActive(available); } if ((Object)(object)band != (Object)null && (Object)(object)burnFront != (Object)null) { bool flag = ((burnDirectionSign > 0f) ? (burnFront.localPosition.y > bandThresholdY) : (burnFront.localPosition.y < bandThresholdY)); band.SetActive(available && flag); } ApplyPhysicalCollider(rootCollider); ApplyPhysicalCollider(physicalCollider); ApplyPickupCollider(); ApplyEmber(); } private void ApplyPhysicalCollider(BoxCollider collider) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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 (!((Object)(object)collider == (Object)null) && !(fullRootColliderSize.y <= 0f)) { float num = Mathf.Max(0.05f, visibleRemaining01); Vector3 val = fullRootColliderSize; val.y = fullRootColliderSize.y * num; Vector3 center = fullRootColliderCenter; center.y = rootColliderMouthEndY + burnDirectionSign * val.y * 0.5f; collider.size = val; collider.center = center; } } private void ApplyPickupCollider() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)pickupCollider == (Object)null) && !(fullPickupColliderSize.y <= 0f)) { Vector3 val = fullPickupColliderSize; val.y = Mathf.Max(0.04f, fullPickupColliderSize.y * visibleRemaining01); Vector3 center = fullPickupColliderCenter; center.y = pickupColliderMouthEndY + burnDirectionSign * val.y * 0.5f; pickupCollider.size = val; pickupCollider.center = center; } } private void ApplyEmber() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_002b: 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) //IL_0032: 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_0095: 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) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: 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_019d: Unknown result type (might be due to invalid IL or missing references) float num = (available ? heat01 : 0f); Color val; Color val2; Color color; if (num > 0f && inhaling) { val = YellowColor; val2 = YellowEmission; color = YellowLightColor; } else { if (num > 0f && !hasCoolingStartHeat) { coolingStartHeat01 = num; hasCoolingStartHeat = true; } CigarEmberCoolingPhase coolingPhase = CigarEmberMath.GetCoolingPhase(num, coolingStartHeat01); float phaseProgress = CigarEmberMath.GetPhaseProgress(coolingPhase, num, coolingStartHeat01); Color val3 = Color.Lerp(Color.black, emberBaseColor, 0.08f); switch (coolingPhase) { case CigarEmberCoolingPhase.YellowToOrange: val = Color.Lerp(YellowColor, OrangeColor, phaseProgress); val2 = Color.Lerp(YellowEmission, OrangeEmission, phaseProgress); color = Color.Lerp(YellowLightColor, OrangeLightColor, phaseProgress); break; case CigarEmberCoolingPhase.OrangeToRed: val = Color.Lerp(OrangeColor, emberBaseColor, phaseProgress); val2 = Color.Lerp(OrangeEmission, emberBaseEmission, phaseProgress); color = Color.Lerp(OrangeLightColor, RedLightColor, phaseProgress); break; case CigarEmberCoolingPhase.RedToDark: val = Color.Lerp(emberBaseColor, val3, phaseProgress); val2 = Color.Lerp(emberBaseEmission, Color.black, phaseProgress); color = Color.Lerp(RedLightColor, Color.black, phaseProgress); break; default: val = val3; val2 = Color.black; color = RedLightColor; break; } } if ((Object)(object)emberRenderer != (Object)null && emberProperties != null) { emberRenderer.GetPropertyBlock(emberProperties); emberProperties.SetColor(ColorProperty, val); emberProperties.SetColor(EmissionColorProperty, val2); emberRenderer.SetPropertyBlock(emberProperties); } if ((Object)(object)emberLight != (Object)null) { emberLight.color = color; emberLight.intensity = 0.15f * num; ((Behaviour)emberLight).enabled = num > 0.001f; } } } public sealed class DriedTobaccoLeafState : MonoBehaviour { public const float RolledCigarSpawnHeight = 0.1f; [SerializeField] private DriedTobaccoLeafVisual leafVisual; private ShipItem item; public int FillCount { get { if (!((Object)(object)item == (Object)null)) { return Mathf.Clamp(Mathf.RoundToInt(item.health), 0, 3); } return 0; } } public void BindVisual(DriedTobaccoLeafVisual newLeafVisual) { leafVisual = newLeafVisual; } private void Awake() { item = ((Component)this).GetComponent(); if ((Object)(object)leafVisual == (Object)null) { leafVisual = ((Component)this).GetComponentInChildren(true); } } private void Start() { SyncFromSavedState(); } public bool TryInsert(ShipItemTobacco tobacco) { if ((Object)(object)tobacco == (Object)null || !((ShipItem)tobacco).sold || FillCount >= 3) { return false; } TobaccoRecipe recipe; bool wasLegacy; if (FillCount == 0) { recipe = default(TobaccoRecipe); } else if (!TobaccoRecipeCodec.TryDecode(Mathf.RoundToInt(item.amount), out recipe, out wasLegacy)) { return false; } if (!recipe.TryAdd(tobacco)) { return false; } item.health = recipe.Count; item.amount = TobaccoRecipeCodec.Encode(recipe); if ((Object)(object)leafVisual != (Object)null) { leafVisual.SetFillCount(recipe.Count); } ((ShipItem)tobacco).DestroyItem(); if ((Object)(object)UISoundPlayer.instance != (Object)null) { UISoundPlayer.instance.PlayUISound((UISounds)4, 0.5f, 0.5f); } RefreshDescription(recipe.Count); return true; } public bool TryRoll() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!TobaccoRecipeCodec.TryDecode(Mathf.RoundToInt(item.amount), out var recipe, out var _) || recipe.Count != FillCount) { return false; } int num = TobaccoRecipeCodec.Encode(recipe); return PrefabReplacement.ReplaceOwnedItem(item, 612, 100f * (float)recipe.Count, -num, Vector3.up * 0.1f); } public void SyncFromSavedState() { if ((Object)(object)item == (Object)null) { item = ((Component)this).GetComponent(); } if ((Object)(object)item == (Object)null) { return; } item.health = Mathf.Clamp(Mathf.RoundToInt(item.health), 0, 3); TobaccoRecipe recipe; bool wasLegacy; if (FillCount == 0) { item.health = 0f; item.amount = 0f; if ((Object)(object)leafVisual != (Object)null) { leafVisual.SetFillCount(0); } ((GoPointerButton)item).description = "dried tobacco leaf\nempty (0 / 3)"; } else if (!TobaccoRecipeCodec.TryDecode(Mathf.RoundToInt(item.amount), out recipe, out wasLegacy) || recipe.Count != FillCount) { RuntimeDiagnostics.Error("Invalid dried-leaf recipe state on instance " + ((Object)this).GetInstanceID() + "; input is disabled until the save is corrected."); if ((Object)(object)leafVisual != (Object)null) { leafVisual.SetFillCount(0); } ((GoPointerButton)item).description = "dried tobacco leaf\ninvalid recipe state"; } else { if ((Object)(object)leafVisual != (Object)null) { leafVisual.SetFillCount(recipe.Count); } RefreshDescription(recipe.Count); } } private void RefreshDescription(int count) { ((GoPointerButton)item).description = "dried tobacco leaf\nfilled: " + count + " / 3\n(R) roll cigar"; } } public sealed class DriedTobaccoLeafVisual : MonoBehaviour { [SerializeField] private GameObject fill0Empty; [SerializeField] private GameObject fill1OneThird; [SerializeField] private GameObject fill2TwoThirds; [SerializeField] private GameObject fill3Full; public void Configure(GameObject newFill0Empty, GameObject newFill1OneThird, GameObject newFill2TwoThirds, GameObject newFill3Full) { fill0Empty = newFill0Empty; fill1OneThird = newFill1OneThird; fill2TwoThirds = newFill2TwoThirds; fill3Full = newFill3Full; } public void SetFillCount(int fillCount) { fillCount = Mathf.Clamp(fillCount, 0, 3); if ((Object)(object)fill0Empty != (Object)null) { fill0Empty.SetActive(fillCount == 0); } if ((Object)(object)fill1OneThird != (Object)null) { fill1OneThird.SetActive(fillCount == 1); } if ((Object)(object)fill2TwoThirds != (Object)null) { fill2TwoThirds.SetActive(fillCount == 2); } if ((Object)(object)fill3Full != (Object)null) { fill3Full.SetActive(fillCount == 3); } } } public sealed class FreshTobaccoLeafState : MonoBehaviour { [SerializeField] private FreshTobaccoLeafVisual leafVisual; private ShipItem item; private void Awake() { item = ((Component)this).GetComponent(); if ((Object)(object)leafVisual == (Object)null) { leafVisual = ((Component)this).GetComponentInChildren(true); } } private void Start() { SyncDryingVisual(); } public void BindVisual(FreshTobaccoLeafVisual newLeafVisual) { leafVisual = newLeafVisual; } public void SyncDryingVisual() { if ((Object)(object)item == (Object)null) { item = ((Component)this).GetComponent(); } if ((Object)(object)item != (Object)null && (Object)(object)leafVisual != (Object)null) { leafVisual.SetDryingHours(item.health); } } public void RemoveFreshVisualDetails() { if (!((Object)(object)leafVisual == (Object)null)) { FreshTobaccoLeafVisual freshTobaccoLeafVisual = leafVisual; leafVisual = null; freshTobaccoLeafVisual.RemoveFreshDetails(); Object.Destroy((Object)(object)freshTobaccoLeafVisual); } } } public sealed class FreshTobaccoLeafVisual : MonoBehaviour { public const float GameHoursPerDay = 24f; public const float WhiteColorGameHours = 72f; public const float FullyDriedGameHours = 144f; public const int VeinsHiddenPerDay = 2; private static readonly int ColorProperty = Shader.PropertyToID("_Color"); [SerializeField] private Renderer bladeRenderer; [SerializeField] private GameObject[] lateralVeins; [SerializeField] private GameObject centralMidrib; [SerializeField] private Renderer[] lateralVeinRenderers; [SerializeField] private Renderer centralMidribRenderer; [SerializeField] private Color freshColor = Color.white; [SerializeField] private Color whiteTobaccoColor = Color.white; [SerializeField] private Color driedLeafColor = Color.white; private MaterialPropertyBlock colorProperties; [SerializeField] private float[] lateralVeinBrightness; [SerializeField] private float centralMidribBrightness = 1f; private float displayedHours = float.NaN; public int LateralVeinCount { get { if (lateralVeins == null) { return 0; } return lateralVeins.Length; } } private void Awake() { CacheDetailRenderersAndBrightness(refreshBrightness: false); } public void Configure(Renderer newBladeRenderer, GameObject[] newLateralVeins, GameObject newCentralMidrib, Color newFreshColor, Color newWhiteTobaccoColor, Color newDriedLeafColor) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0026: 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) bladeRenderer = newBladeRenderer; lateralVeins = newLateralVeins; centralMidrib = newCentralMidrib; freshColor = newFreshColor; whiteTobaccoColor = newWhiteTobaccoColor; driedLeafColor = newDriedLeafColor; CacheDetailRenderersAndBrightness(refreshBrightness: true); displayedHours = float.NaN; } public void SetDryingHours(float gameHours) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) float num = Mathf.Clamp(gameHours, 0f, 144f); if (!float.IsNaN(displayedHours) && Mathf.Abs(displayedHours - num) < 0.0001f) { return; } displayedHours = num; ApplyColor(EvaluateDryingColor(num, freshColor, whiteTobaccoColor, driedLeafColor)); int hiddenVeinCount = GetHiddenVeinCount(num, LateralVeinCount); for (int i = 0; i < LateralVeinCount; i++) { if ((Object)(object)lateralVeins[i] != (Object)null) { lateralVeins[i].SetActive(i >= hiddenVeinCount); } } if ((Object)(object)centralMidrib != (Object)null) { centralMidrib.SetActive(true); } } public void RemoveFreshDetails() { if (lateralVeins != null) { for (int i = 0; i < lateralVeins.Length; i++) { if ((Object)(object)lateralVeins[i] != (Object)null) { Object.Destroy((Object)(object)lateralVeins[i]); } } } if ((Object)(object)centralMidrib != (Object)null) { Object.Destroy((Object)(object)centralMidrib); } } public static Color EvaluateDryingColor(float gameHours, Color fresh, Color white, Color dried) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(gameHours, 0f, 144f); if (num <= 72f) { return Color.Lerp(fresh, white, num / 72f); } return Color.Lerp(white, dried, (num - 72f) / 72f); } public static int GetHiddenVeinCount(float gameHours, int veinCount) { return Mathf.Clamp(Mathf.FloorToInt(Mathf.Max(0f, gameHours) / 24f) * 2, 0, Mathf.Max(0, veinCount)); } private void ApplyColor(Color color) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) if (colorProperties == null) { colorProperties = new MaterialPropertyBlock(); } ApplyRendererColor(bladeRenderer, color); if (lateralVeinRenderers != null) { for (int i = 0; i < lateralVeinRenderers.Length; i++) { float brightness = ((lateralVeinBrightness != null && i < lateralVeinBrightness.Length) ? lateralVeinBrightness[i] : 1f); ApplyRendererColor(lateralVeinRenderers[i], ApplyBrightness(color, brightness)); } } ApplyRendererColor(centralMidribRenderer, ApplyBrightness(color, centralMidribBrightness)); } public static Color ApplyBrightness(Color color, float brightness) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) return new Color(Mathf.Clamp01(color.r * brightness), Mathf.Clamp01(color.g * brightness), Mathf.Clamp01(color.b * brightness), color.a); } private void ApplyRendererColor(Renderer target, Color color) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { colorProperties.Clear(); target.GetPropertyBlock(colorProperties); colorProperties.SetColor(ColorProperty, color); target.SetPropertyBlock(colorProperties); } } private void CacheDetailRenderersAndBrightness(bool refreshBrightness) { int lateralVeinCount = LateralVeinCount; if (lateralVeinRenderers == null || lateralVeinRenderers.Length != lateralVeinCount) { lateralVeinRenderers = (Renderer[])(object)new Renderer[lateralVeinCount]; } bool flag = lateralVeinBrightness == null || lateralVeinBrightness.Length != lateralVeinCount; if (flag) { lateralVeinBrightness = new float[lateralVeinCount]; } for (int i = 0; i < lateralVeinCount; i++) { if ((Object)(object)lateralVeinRenderers[i] == (Object)null && (Object)(object)lateralVeins[i] != (Object)null) { lateralVeinRenderers[i] = lateralVeins[i].GetComponentInChildren(true); } if (refreshBrightness || flag) { lateralVeinBrightness[i] = GetBrightnessRatio(lateralVeinRenderers[i]); } } if ((Object)(object)centralMidribRenderer == (Object)null && (Object)(object)centralMidrib != (Object)null) { centralMidribRenderer = centralMidrib.GetComponentInChildren(true); } if (refreshBrightness || flag) { centralMidribBrightness = GetBrightnessRatio(centralMidribRenderer); } } private float GetBrightnessRatio(Renderer target) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) if ((Object)(object)target == (Object)null || (Object)(object)target.sharedMaterial == (Object)null || !target.sharedMaterial.HasProperty(ColorProperty)) { return 1f; } Color color = target.sharedMaterial.GetColor(ColorProperty); float luminance = GetLuminance(freshColor); if (!(luminance > 0.001f)) { return 1f; } return Mathf.Clamp(GetLuminance(color) / luminance, 0f, 4f); } private static float GetLuminance(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return color.r * 0.2126f + color.g * 0.7152f + color.b * 0.0722f; } } public sealed class RackOnlyDrying : MonoBehaviour { public const float LooseTobaccoRequiredGameHours = 72f; public const float FreshLeafRequiredGameHours = 144f; [SerializeField] private int resultPrefabIndex; private readonly HashSet racks = new HashSet(); private ShipItem item; private Coroutine dryingRoutine; public int ResultPrefabIndex => resultPrefabIndex; public float CurrentRequiredGameHours => GetRequiredGameHours(); private void Awake() { item = ((Component)this).GetComponent(); } private void Start() { SyncFromSavedState(); } private void OnDisable() { StopDrying(); racks.Clear(); } private void OnTriggerEnter(Collider other) { RegisterRack(other); } private void OnTriggerStay(Collider other) { RegisterRack(other); } private void OnTriggerExit(Collider other) { DryingRackCol val = FindRack(other); if (!((Object)(object)val == (Object)null) && racks.Remove(val) && racks.Count == 0) { StopDrying(); } } public void ConfigureResultPrefab(int newResultPrefabIndex) { resultPrefabIndex = newResultPrefabIndex; } public void SyncFromSavedState() { if ((Object)(object)item == (Object)null) { item = ((Component)this).GetComponent(); } if (!((Object)(object)item == (Object)null)) { item.health = Mathf.Clamp(item.health, 0f, GetRequiredGameHours()); FreshTobaccoLeafState component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null) { component.SyncDryingVisual(); } } } private void RegisterRack(Collider other) { DryingRackCol val = FindRack(other); if ((Object)(object)val != (Object)null && racks.Add(val) && dryingRoutine == null) { dryingRoutine = ((MonoBehaviour)this).StartCoroutine(DryWhileRacked()); } } private static DryingRackCol FindRack(Collider other) { if ((Object)(object)other == (Object)null) { return null; } DryingRackCol component = ((Component)other).GetComponent(); if (!((Object)(object)component != (Object)null)) { return ((Component)other).GetComponentInParent(); } return component; } private IEnumerator DryWhileRacked() { while (racks.Count > 0) { Sun sun = Sun.sun; if ((Object)(object)item != (Object)null && item.sold && (Object)(object)sun != (Object)null && !Sun.SunPaused() && resultPrefabIndex > 0) { float requiredGameHours = GetRequiredGameHours(); item.health = Mathf.Min(requiredGameHours, item.health + Time.deltaTime * sun.timescale); FreshTobaccoLeafState component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null) { component.SyncDryingVisual(); } if (item.health >= requiredGameHours) { if (TryAdvanceFreshLeafInPlace() || TryAdvanceLooseTobaccoInPlace()) { if (resultPrefabIndex <= 0) { dryingRoutine = null; ((Behaviour)this).enabled = false; yield break; } yield return null; continue; } RuntimeDiagnostics.Error("Could not advance rack drying from prefab " + GetCurrentPrefabIndex() + " to " + resultPrefabIndex + " in place. The physical item was preserved; replacement spawning was not attempted."); dryingRoutine = null; ((Behaviour)this).enabled = false; yield break; } } yield return null; } dryingRoutine = null; } private bool TryAdvanceFreshLeafInPlace() { FreshTobaccoLeafState freshTobaccoLeafState = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent() : null); SaveablePrefab val = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent() : null); if ((Object)(object)freshTobaccoLeafState == (Object)null || (Object)(object)val == (Object)null || !TobaccoDryingChain.IsStageTransition(val.prefabIndex, resultPrefabIndex)) { return false; } if (!TryResolveTarget(resultPrefabIndex, out var targetPrefab, out var targetItem, out var targetRenderer) || (Object)(object)targetPrefab.GetComponent() == (Object)null) { return false; } Renderer component = ((Component)item).GetComponent(); MeshFilter component2 = ((Component)item).GetComponent(); MeshFilter component3 = targetPrefab.GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component3.sharedMesh == (Object)null) { return false; } Transform val2 = CloneDirectChild(targetPrefab.transform, "Fill0_Empty"); Transform val3 = CloneDirectChild(targetPrefab.transform, "Fill1_OneThird"); Transform val4 = CloneDirectChild(targetPrefab.transform, "Fill2_TwoThirds"); Transform val5 = CloneDirectChild(targetPrefab.transform, "Fill3_Full"); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null) { DestroyClone(val2); DestroyClone(val3); DestroyClone(val4); DestroyClone(val5); return false; } component2.sharedMesh = component3.sharedMesh; CopyRenderer(component, targetRenderer); CopyItemPresentation(item, targetItem); item.health = 0f; item.amount = 0f; val.prefabIndex = resultPrefabIndex; ((Object)((Component)item).gameObject).name = ((Object)targetPrefab).name + "(Clone)"; val2.SetParent(((Component)item).transform, false); val3.SetParent(((Component)item).transform, false); val4.SetParent(((Component)item).transform, false); val5.SetParent(((Component)item).transform, false); DriedTobaccoLeafVisual driedTobaccoLeafVisual = ((Component)item).gameObject.AddComponent(); driedTobaccoLeafVisual.Configure(((Component)val2).gameObject, ((Component)val3).gameObject, ((Component)val4).gameObject, ((Component)val5).gameObject); DriedTobaccoLeafState driedTobaccoLeafState = ((Component)item).gameObject.AddComponent(); driedTobaccoLeafState.BindVisual(driedTobaccoLeafVisual); driedTobaccoLeafState.SyncFromSavedState(); if ((Object)(object)item.itemRigidbodyC != (Object)null) { item.itemRigidbodyC.UpdateMass(); } freshTobaccoLeafState.RemoveFreshVisualDetails(); Object.Destroy((Object)(object)freshTobaccoLeafState); resultPrefabIndex = 0; RuntimeDiagnostics.Info("Dried fresh tobacco leaf in place while preserving its collider, rack contact, pose, and save identity."); return true; } private bool TryAdvanceLooseTobaccoInPlace() { ShipItem obj = item; ShipItemTobacco val = (ShipItemTobacco)(object)((obj is ShipItemTobacco) ? obj : null); SaveablePrefab val2 = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent() : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !TobaccoDryingChain.IsStageTransition(val2.prefabIndex, resultPrefabIndex)) { return false; } if (!TryResolveTarget(resultPrefabIndex, out var targetPrefab, out var targetItem, out var targetRenderer)) { return false; } ShipItemTobacco val3 = (((Object)(object)targetPrefab != (Object)null) ? targetPrefab.GetComponent() : null); Renderer component = ((Component)item).GetComponent(); if ((Object)(object)val3 == (Object)null || (Object)(object)component == (Object)null || (Object)(object)targetRenderer == (Object)null) { return false; } int num = resultPrefabIndex; CopyRenderer(component, targetRenderer); MeshFilter component2 = ((Component)item).GetComponent(); MeshFilter component3 = targetPrefab.GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null) { component2.sharedMesh = component3.sharedMesh; } ((Object)((Component)item).gameObject).name = ((Object)targetPrefab).name + "(Clone)"; CopyItemPresentation(item, targetItem); item.amount = ((ShipItem)val3).amount; item.health = 0f; val.tobaccoType = val3.tobaccoType; val2.prefabIndex = num; if ((Object)(object)item.itemRigidbodyC != (Object)null) { item.itemRigidbodyC.UpdateMass(); } resultPrefabIndex = (TobaccoDryingChain.TryGetNextStage(num, out var num2) ? num2 : 0); RuntimeDiagnostics.Info("Advanced loose tobacco to prefab " + num + " in place while preserving its rack contact and save identity."); return true; } private Transform CloneDirectChild(Transform targetRoot, string childName) { Transform val = targetRoot.Find(childName); if ((Object)(object)val == (Object)null) { return null; } GameObject obj = Object.Instantiate(((Component)val).gameObject); ((Object)obj).name = ((Object)val).name; return obj.transform; } private static void DestroyClone(Transform clone) { if ((Object)(object)clone != (Object)null) { Object.Destroy((Object)(object)((Component)clone).gameObject); } } private static bool TryResolveTarget(int prefabIndex, out GameObject targetPrefab, out ShipItem targetItem, out Renderer targetRenderer) { targetPrefab = null; targetItem = null; targetRenderer = null; PrefabsDirectory instance = PrefabsDirectory.instance; if ((Object)(object)instance == (Object)null || instance.directory == null || prefabIndex < 0 || prefabIndex >= instance.directory.Length) { return false; } targetPrefab = instance.directory[prefabIndex]; if ((Object)(object)targetPrefab == (Object)null) { return false; } targetItem = targetPrefab.GetComponent(); targetRenderer = targetPrefab.GetComponent(); if ((Object)(object)targetItem != (Object)null) { return (Object)(object)targetRenderer != (Object)null; } return false; } private int GetCurrentPrefabIndex() { SaveablePrefab val = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent() : null); if (!((Object)(object)val != (Object)null)) { return -1; } return val.prefabIndex; } private float GetRequiredGameHours() { if (!((Object)(object)item != (Object)null) || !((Object)(object)((Component)item).GetComponent() != (Object)null)) { return 72f; } return 144f; } private static void CopyRenderer(Renderer target, Renderer source) { //IL_001a: 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_003e: Unknown result type (might be due to invalid IL or missing references) target.sharedMaterials = source.sharedMaterials; target.enabled = source.enabled; target.shadowCastingMode = source.shadowCastingMode; target.receiveShadows = source.receiveShadows; target.lightProbeUsage = source.lightProbeUsage; target.reflectionProbeUsage = source.reflectionProbeUsage; } private static void CopyItemPresentation(ShipItem target, ShipItem source) { //IL_0026: 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) target.name = source.name; target.mass = source.mass; target.value = source.value; target.category = source.category; target.inventoryScale = source.inventoryScale; target.inventoryRotation = source.inventoryRotation; target.inventoryRotationX = source.inventoryRotationX; target.floaterHeight = source.floaterHeight; target.wallAttachment = source.wallAttachment; target.delayLook = source.delayLook; ((PickupableItem)target).big = ((PickupableItem)source).big; ((PickupableItem)target).holdDistance = ((PickupableItem)source).holdDistance; ((PickupableItem)target).furniturePlaceHeight = ((PickupableItem)source).furniturePlaceHeight; ((PickupableItem)target).holdHeight = ((PickupableItem)source).holdHeight; ((PickupableItem)target).itemClickDistance = ((PickupableItem)source).itemClickDistance; } private void StopDrying() { if (dryingRoutine != null) { ((MonoBehaviour)this).StopCoroutine(dryingRoutine); dryingRoutine = null; } } } public sealed class TobaccoPlantPotState : MonoBehaviour { [SerializeField] private TobaccoPlantVisual plantVisual; private ShipItem item; private Coroutine growthRoutine; public float StoredWater { get { if (!((Object)(object)item == (Object)null)) { return Mathf.Clamp(item.health, 0f, 15f); } return 0f; } } public float GrowthGameHours { get { if (!((Object)(object)item == (Object)null)) { return Mathf.Clamp(item.amount, 0f, 360f); } return 0f; } } public int CompletedGrowthDays => Mathf.Clamp(Mathf.FloorToInt(GrowthGameHours / 24f), 0, 15); public bool FullyGrown => GrowthGameHours >= 360f; private void Awake() { item = ((Component)this).GetComponent(); if ((Object)(object)plantVisual == (Object)null) { plantVisual = ((Component)this).GetComponentInChildren(true); } } private void Start() { SyncFromSavedState(); } private void OnEnable() { if (growthRoutine == null) { growthRoutine = ((MonoBehaviour)this).StartCoroutine(GrowUsingGameTime()); } } private void OnDisable() { if (growthRoutine != null) { ((MonoBehaviour)this).StopCoroutine(growthRoutine); growthRoutine = null; } } public void SyncFromSavedState() { if ((Object)(object)item == (Object)null) { item = ((Component)this).GetComponent(); } if (!((Object)(object)item == (Object)null)) { item.health = Mathf.Clamp(item.health, 0f, 15f); item.amount = Mathf.Clamp(item.amount, 0f, 360f); if ((Object)(object)plantVisual != (Object)null) { plantVisual.SetHarvestReady(FullyGrown); } RefreshDescription(); } } public bool TryAcceptWater(ShipItemBottle source) { if ((Object)(object)source == (Object)null || !((ShipItem)source).sold || !Mathf.Approximately(((ShipItem)source).amount, 1f) || ((ShipItem)source).health <= 0f || StoredWater >= 15f) { return false; } Good component = ((Component)source).GetComponent(); if ((Object)(object)component != (Object)null && component.GetMissionIndex() > -1) { return false; } float num = Mathf.Min(((ShipItem)source).health, 15f - item.health); ((ShipItem)source).health = ((ShipItem)source).health - num; ShipItem obj = item; obj.health += num; if (((ShipItem)source).health <= 0f) { source.EmptyBottle(); } else { ((ShipItem)source).UpdateLookText(); } if ((Object)(object)((ShipItem)source).itemRigidbodyC != (Object)null) { ((ShipItem)source).itemRigidbodyC.UpdateMass(); } if ((Object)(object)UISoundPlayer.instance != (Object)null) { UISoundPlayer.instance.PlayLiquidPourSound(); } RefreshDescription(); return true; } public bool TryHarvest() { //IL_002a: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_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_0075: 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) if (!FullyGrown || !PrefabReplacement.CanSpawn(611)) { return false; } List list = new List(2); for (int i = 0; i < 2; i++) { Vector3 val = ((Component)this).transform.right * (((i == 0) ? (-1f) : 1f) * 0.04f); ShipItem val2 = PrefabReplacement.SpawnOwned(611, ((Component)this).transform.position + ((Component)this).transform.up * 0.5f + val, ((Component)this).transform.rotation, item, 0f, 0f); if ((Object)(object)val2 != (Object)null) { list.Add(val2); } } if (list.Count != 2) { for (int j = 0; j < list.Count; j++) { list[j].DestroyItem(); } RuntimeDiagnostics.Error("Tobacco harvest could not create both leaves; partial output was rolled back and growth was not reset."); return false; } item.amount = 0f; SyncFromSavedState(); return true; } private IEnumerator GrowUsingGameTime() { while (true) { Sun sun = Sun.sun; if ((Object)(object)item != (Object)null && item.sold && (Object)(object)sun != (Object)null && !Sun.SunPaused() && !FullyGrown && item.health >= 1f) { float storedWater = item.health; float growthGameHours = item.amount; int num = GrowthMath.Advance(ref storedWater, ref growthGameHours, Time.deltaTime * sun.timescale); item.health = storedWater; item.amount = growthGameHours; if (num > 0 || FullyGrown) { SyncFromSavedState(); } } yield return null; } } private void RefreshDescription() { if (!((Object)(object)item == (Object)null)) { ((GoPointerButton)item).description = (FullyGrown ? ("tobacco pot\nfully grown\nwater: " + item.health.ToString("0") + " / 15\n(R) harvest") : ("tobacco pot\ngrowth: " + CompletedGrowthDays + " / 15 days\nwater: " + item.health.ToString("0") + " / 15")); } } } public sealed class TobaccoPlantVisual : MonoBehaviour { [SerializeField] private GameObject plantBase; [SerializeField] private GameObject harvestLeaves; public void SetHarvestReady(bool ready) { if ((Object)(object)plantBase != (Object)null && !plantBase.activeSelf) { plantBase.SetActive(true); } if ((Object)(object)harvestLeaves != (Object)null) { harvestLeaves.SetActive(ready); } } } public static class GrowthMath { public const float Capacity = 15f; public const float GameHoursPerDay = 24f; public const int RequiredDays = 15; public const float RequiredGameHours = 360f; public static int Advance(ref float storedWater, ref float growthGameHours, float availableGameHours) { storedWater = Mathf.Clamp(storedWater, 0f, 15f); growthGameHours = Mathf.Clamp(growthGameHours, 0f, 360f); availableGameHours = Mathf.Max(0f, availableGameHours); int num = 0; while (availableGameHours > 1E-05f && storedWater >= 1f && growthGameHours < 360f) { float num2 = Mathf.Min((float)(Mathf.FloorToInt(growthGameHours / 24f) + 1) * 24f, 360f); float num3 = Mathf.Min(availableGameHours, num2 - growthGameHours); if (num3 <= 0f) { break; } growthGameHours += num3; availableGameHours -= num3; if (growthGameHours >= num2 - 0.0001f) { growthGameHours = num2; storedWater = Mathf.Max(0f, storedWater - 1f); num++; } } return num; } } public static class PrefabReplacement { private static readonly GameObject[] CustomPrefabs = (GameObject[])(object)new GameObject[4]; public static void RegisterCustomPrefab(int index, GameObject prefab) { int num = index - 610; if (num < 0 || num >= CustomPrefabs.Length) { throw new ArgumentOutOfRangeException("index"); } CustomPrefabs[num] = prefab; } public static void ClearCustomPrefabs() { for (int i = 0; i < CustomPrefabs.Length; i++) { CustomPrefabs[i] = null; } } public static bool CanSpawn(int prefabIndex) { if ((Object)(object)ResolvePrefab(prefabIndex) != (Object)null) { return (Object)(object)SaveLoadManager.instance != (Object)null; } return false; } public static ShipItem SpawnOwned(int prefabIndex, Vector3 position, Quaternion rotation, ShipItem context, float health, float amount) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) GameObject val = ResolvePrefab(prefabIndex); if ((Object)(object)val == (Object)null) { return null; } if ((Object)(object)SaveLoadManager.instance == (Object)null) { RuntimeDiagnostics.Error("Cannot spawn prefab " + prefabIndex + ": SaveLoadManager is unavailable."); return null; } GameObject val2 = Object.Instantiate(val, position, rotation); ShipItem component = val2.GetComponent(); SaveablePrefab component2 = val2.GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { RuntimeDiagnostics.Error("Registered prefab " + prefabIndex + " lost its ShipItem/SaveablePrefab contract."); Object.Destroy((Object)(object)val2); return null; } if ((Object)(object)context != (Object)null) { SaveablePrefab component3 = ((Component)context).GetComponent(); if ((Object)(object)component3 != (Object)null) { component2.SetParentObject(component3.GetParentObject()); component2.currentCrateId = component3.currentCrateId; } if ((Object)(object)((Component)context).transform.parent != (Object)null) { val2.transform.SetParent(((Component)context).transform.parent, true); } } component.sold = true; component.health = health; component.amount = amount; RuntimeStateSynchronizer.Sync(component, snapCigar: true); component2.RegisterToSave(); return component; } public static bool ReplaceOwnedItem(ShipItem source, int resultPrefabIndex, float replacementHealth, float replacementAmount) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) return ReplaceOwnedItem(source, resultPrefabIndex, replacementHealth, replacementAmount, Vector3.zero); } public static bool ReplaceOwnedItem(ShipItem source, int resultPrefabIndex, float replacementHealth, float replacementAmount, Vector3 worldPositionOffset) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!CanTransform(source)) { return false; } if ((Object)(object)SpawnOwned(resultPrefabIndex, ((Component)source).transform.position + worldPositionOffset, ((Component)source).transform.rotation, source, replacementHealth, replacementAmount) == (Object)null) { return false; } if ((Object)(object)source.itemRigidbodyC != (Object)null) { source.FreezeItem(); } else { Collider component = ((Component)source).GetComponent(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } source.DestroyItem(); return true; } private static bool CanTransform(ShipItem source) { if ((Object)(object)source == (Object)null || !source.sold) { return false; } SaveablePrefab component = ((Component)source).GetComponent(); if ((Object)(object)component == (Object)null) { return false; } if (component.currentCrateId > 0) { RuntimeDiagnostics.Error("Refusing to transform crate-contained item " + source.name + "."); return false; } if ((Object)(object)source.itemRigidbodyC != (Object)null && source.GetCurrentInventorySlot() >= 0) { RuntimeDiagnostics.Error("Refusing to transform inventory-held item " + source.name + "."); return false; } return true; } private static GameObject ResolvePrefab(int prefabIndex) { PrefabsDirectory instance = PrefabsDirectory.instance; if ((Object)(object)instance == (Object)null || instance.directory == null || prefabIndex < 0 || prefabIndex >= instance.directory.Length) { RuntimeDiagnostics.Error("Prefab directory cannot resolve index " + prefabIndex + "."); return null; } GameObject val = instance.directory[prefabIndex]; int num = prefabIndex - 610; if (num >= 0 && num < CustomPrefabs.Length && (Object)(object)val != (Object)(object)CustomPrefabs[num]) { RuntimeDiagnostics.Error("Custom prefab index " + prefabIndex + " is not the registered bundled asset."); return null; } return val; } } public static class RuntimeConstants { public const int FirstVanillaPipePrefabIndex = 300; public const int LastVanillaPipePrefabIndex = 302; public const int TobaccoPotPrefabIndex = 610; public const int FreshTobaccoLeafPrefabIndex = 611; public const int CigarPrefabIndex = 612; public const int DriedTobaccoLeafPrefabIndex = 613; public const int WhiteTobaccoPrefabIndex = 310; public const int GreenTobaccoPrefabIndex = 312; public const int BlackTobaccoPrefabIndex = 314; public const int BrownTobaccoPrefabIndex = 316; public const int BlueTobaccoPrefabIndex = 318; } public static class RuntimeDiagnostics { public static Action InfoSink; public static Action WarningSink; public static Action ErrorSink; public static void Info(string message) { if (InfoSink != null) { InfoSink(message); } else { Debug.Log((object)("Tobacco pot and cigar: " + message)); } } public static void Warning(string message) { if (WarningSink != null) { WarningSink(message); } else { Debug.LogWarning((object)("Tobacco pot and cigar: " + message)); } } public static void Error(string message) { if (ErrorSink != null) { ErrorSink(message); } else { Debug.LogError((object)("Tobacco pot and cigar: " + message)); } } public static void Reset() { InfoSink = null; WarningSink = null; ErrorSink = null; } } public static class RuntimeStateSynchronizer { public static void Sync(ShipItem item, bool snapCigar) { if (!((Object)(object)item == (Object)null)) { TobaccoPlantPotState component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null) { component.SyncFromSavedState(); } RackOnlyDrying component2 = ((Component)item).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.SyncFromSavedState(); } DriedTobaccoLeafState component3 = ((Component)item).GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.SyncFromSavedState(); } CigarRuntimeState component4 = ((Component)item).GetComponent(); if ((Object)(object)component4 != (Object)null && !component4.TryDestroyIfConsumed()) { component4.RefreshValue(); component4.SyncVisuals(snapCigar, 0f, inhaling: false); } } } } public enum CigarTobaccoType { White = 1, Green, Black, Brown, Blue } public struct TobaccoBlend { public int White; public int Green; public int Black; public int Brown; public int Blue; public int Count => White + Green + Black + Brown + Blue; public bool TryAdd(ShipItemTobacco tobacco) { if (TobaccoTypeResolver.TryResolve(tobacco, out var tobaccoType)) { return TryAdd(tobaccoType); } return false; } public bool TryAdd(CigarTobaccoType tobaccoType) { if (Count >= 3) { return false; } switch (tobaccoType) { case CigarTobaccoType.White: White++; return true; case CigarTobaccoType.Green: Green++; return true; case CigarTobaccoType.Black: Black++; return true; case CigarTobaccoType.Brown: Brown++; return true; case CigarTobaccoType.Blue: Blue++; return true; default: return false; } } } public static class TobaccoBlendCodec { public static int Encode(TobaccoBlend blend) { if (blend.Count < 1 || blend.Count > 3 || blend.White < 0 || blend.White > 3 || blend.Green < 0 || blend.Green > 3 || blend.Black < 0 || blend.Black > 3 || blend.Brown < 0 || blend.Brown > 3 || blend.Blue < 0 || blend.Blue > 3) { throw new ArgumentOutOfRangeException("blend"); } return 1 + blend.White + (blend.Green << 2) + (blend.Black << 4) + (blend.Brown << 6) + (blend.Blue << 8); } public static bool TryDecode(int code, out TobaccoBlend blend) { if (TobaccoRecipeCodec.TryDecodeOrdered(code, out var recipe)) { blend = recipe.ToBlend(); return true; } return TryDecodeLegacy(code, out blend); } internal static bool TryDecodeLegacy(int code, out TobaccoBlend blend) { blend = default(TobaccoBlend); if (code <= 0 || code >= 4096) { return false; } int num = code - 1; blend.White = num & 3; blend.Green = (num >> 2) & 3; blend.Black = (num >> 4) & 3; blend.Brown = (num >> 6) & 3; blend.Blue = (num >> 8) & 3; int num2 = 1023; if ((num & ~num2) == 0 && blend.Count >= 1) { return blend.Count <= 3; } return false; } public static bool TryDecodeCigar(float itemAmount, out TobaccoBlend blend) { blend = default(TobaccoBlend); int num = Mathf.RoundToInt(itemAmount); if (num < 0) { return TryDecode(-num, out blend); } return false; } } public static class TobaccoDryingChain { public static bool TryGetNextStage(int sourcePrefabIndex, out int resultPrefabIndex) { switch (sourcePrefabIndex) { case 611: resultPrefabIndex = 613; return true; case 312: resultPrefabIndex = 310; return true; case 310: resultPrefabIndex = 316; return true; case 316: resultPrefabIndex = 314; return true; default: resultPrefabIndex = 0; return false; } } public static bool IsStageTransition(int sourcePrefabIndex, int resultPrefabIndex) { if (TryGetNextStage(sourcePrefabIndex, out var resultPrefabIndex2)) { return resultPrefabIndex2 == resultPrefabIndex; } return false; } } public struct TobaccoRecipe { private CigarTobaccoType first; private CigarTobaccoType second; private CigarTobaccoType third; private int count; public int Count => count; public bool IsFullSingleType { get { if (count == 3 && first == second) { return second == third; } return false; } } public CigarTobaccoType GetAt(int index) { switch (index) { case 0: if (count > 0) { return first; } break; case 1: if (count > 1) { return second; } break; case 2: if (count > 2) { return third; } break; } throw new ArgumentOutOfRangeException("index"); } public bool TryAdd(CigarTobaccoType tobaccoType) { if (count >= 3 || !TobaccoTypeResolver.IsSupported(tobaccoType)) { return false; } if (count == 0) { first = tobaccoType; } else if (count == 1) { second = tobaccoType; } else { third = tobaccoType; } count++; return true; } public bool TryAdd(ShipItemTobacco tobacco) { if (TobaccoTypeResolver.TryResolve(tobacco, out var tobaccoType)) { return TryAdd(tobaccoType); } return false; } public TobaccoBlend ToBlend() { TobaccoBlend result = default(TobaccoBlend); for (int i = 0; i < count; i++) { result.TryAdd(GetAt(i)); } return result; } internal static TobaccoRecipe FromLegacyBlend(TobaccoBlend blend) { TobaccoRecipe recipe = default(TobaccoRecipe); AddCopies(ref recipe, CigarTobaccoType.Green, blend.Green); AddCopies(ref recipe, CigarTobaccoType.White, blend.White); AddCopies(ref recipe, CigarTobaccoType.Brown, blend.Brown); AddCopies(ref recipe, CigarTobaccoType.Blue, blend.Blue); AddCopies(ref recipe, CigarTobaccoType.Black, blend.Black); return recipe; } private static void AddCopies(ref TobaccoRecipe recipe, CigarTobaccoType tobaccoType, int copies) { for (int i = 0; i < copies; i++) { recipe.TryAdd(tobaccoType); } } } public static class TobaccoRecipeCodec { public const int OrderedRecipeMarker = 4096; private const int Radix = 6; private const int MaximumPayload = 216; public static int Encode(TobaccoRecipe recipe) { if (recipe.Count < 1 || recipe.Count > 3) { throw new ArgumentOutOfRangeException("recipe"); } int num = 0; int num2 = 1; for (int i = 0; i < recipe.Count; i++) { num += (int)recipe.GetAt(i) * num2; num2 *= 6; } return 4096 + num; } public static bool TryDecode(int code, out TobaccoRecipe recipe, out bool wasLegacy) { wasLegacy = false; if (TryDecodeOrdered(code, out recipe)) { return true; } if (!TobaccoBlendCodec.TryDecodeLegacy(code, out var blend)) { recipe = default(TobaccoRecipe); return false; } recipe = TobaccoRecipe.FromLegacyBlend(blend); wasLegacy = true; return recipe.Count == blend.Count; } public static bool TryDecodeCigar(float itemAmount, out TobaccoRecipe recipe, out bool wasLegacy) { recipe = default(TobaccoRecipe); wasLegacy = false; int num = Mathf.RoundToInt(itemAmount); if (num < 0) { return TryDecode(-num, out recipe, out wasLegacy); } return false; } internal static bool TryDecodeOrdered(int code, out TobaccoRecipe recipe) { recipe = default(TobaccoRecipe); int num = code - 4096; if (num <= 0 || num >= 216) { return false; } int num2 = num % 6; int num3 = num / 6 % 6; int num4 = num / 36 % 6; if (!IsValidDigit(num2) || (num3 == 0 && num4 != 0) || (num3 != 0 && !IsValidDigit(num3)) || (num4 != 0 && !IsValidDigit(num4))) { return false; } recipe.TryAdd((CigarTobaccoType)num2); if (num3 != 0) { recipe.TryAdd((CigarTobaccoType)num3); } if (num4 != 0) { recipe.TryAdd((CigarTobaccoType)num4); } return true; } private static bool IsValidDigit(int value) { if (value >= 1) { return value <= 5; } return false; } } public static class TobaccoTypeResolver { public static bool TryResolve(ShipItemTobacco tobacco, out CigarTobaccoType tobaccoType) { tobaccoType = (CigarTobaccoType)0; if ((Object)(object)tobacco == (Object)null) { return false; } SaveablePrefab component = ((Component)tobacco).GetComponent(); if (((Object)(object)component != (Object)null && component.prefabIndex == 318) || tobacco.tobaccoType == 5) { tobaccoType = CigarTobaccoType.Blue; return true; } tobaccoType = (CigarTobaccoType)tobacco.tobaccoType; return IsSupported(tobaccoType); } public static bool IsSupported(CigarTobaccoType tobaccoType) { if (tobaccoType >= CigarTobaccoType.White) { return tobaccoType <= CigarTobaccoType.Blue; } return false; } } }