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 "<color=#" + hex + ">" + letter + "</color>";
}
}
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<ShipItemPipe>();
if ((Object)(object)cigarVisual == (Object)null)
{
cigarVisual = ((Component)this).GetComponentInChildren<CigarVisualController>(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<ShipItemPipe>();
}
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<ShipItemPipe>();
}
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<ShipItemPipe>();
}
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<ShipItem>();
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<BoxCollider>();
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<BoxCollider>();
}
}
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<ShipItem>();
if ((Object)(object)leafVisual == (Object)null)
{
leafVisual = ((Component)this).GetComponentInChildren<DriedTobaccoLeafVisual>(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<ShipItem>();
}
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<ShipItem>();
if ((Object)(object)leafVisual == (Object)null)
{
leafVisual = ((Component)this).GetComponentInChildren<FreshTobaccoLeafVisual>(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<ShipItem>();
}
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<Renderer>(true);
}
if (refreshBrightness || flag)
{
lateralVeinBrightness[i] = GetBrightnessRatio(lateralVeinRenderers[i]);
}
}
if ((Object)(object)centralMidribRenderer == (Object)null && (Object)(object)centralMidrib != (Object)null)
{
centralMidribRenderer = centralMidrib.GetComponentInChildren<Renderer>(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<DryingRackCol> racks = new HashSet<DryingRackCol>();
private ShipItem item;
private Coroutine dryingRoutine;
public int ResultPrefabIndex => resultPrefabIndex;
public float CurrentRequiredGameHours => GetRequiredGameHours();
private void Awake()
{
item = ((Component)this).GetComponent<ShipItem>();
}
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<ShipItem>();
}
if (!((Object)(object)item == (Object)null))
{
item.health = Mathf.Clamp(item.health, 0f, GetRequiredGameHours());
FreshTobaccoLeafState component = ((Component)item).GetComponent<FreshTobaccoLeafState>();
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<DryingRackCol>();
if (!((Object)(object)component != (Object)null))
{
return ((Component)other).GetComponentInParent<DryingRackCol>();
}
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<FreshTobaccoLeafState>();
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<FreshTobaccoLeafState>() : null);
SaveablePrefab val = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent<SaveablePrefab>() : 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<DriedTobaccoLeafState>() == (Object)null)
{
return false;
}
Renderer component = ((Component)item).GetComponent<Renderer>();
MeshFilter component2 = ((Component)item).GetComponent<MeshFilter>();
MeshFilter component3 = targetPrefab.GetComponent<MeshFilter>();
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>();
driedTobaccoLeafVisual.Configure(((Component)val2).gameObject, ((Component)val3).gameObject, ((Component)val4).gameObject, ((Component)val5).gameObject);
DriedTobaccoLeafState driedTobaccoLeafState = ((Component)item).gameObject.AddComponent<DriedTobaccoLeafState>();
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<SaveablePrefab>() : 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<ShipItemTobacco>() : null);
Renderer component = ((Component)item).GetComponent<Renderer>();
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>();
MeshFilter component3 = targetPrefab.GetComponent<MeshFilter>();
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<GameObject>(((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<ShipItem>();
targetRenderer = targetPrefab.GetComponent<Renderer>();
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<SaveablePrefab>() : 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<FreshTobaccoLeafState>() != (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<ShipItem>();
if ((Object)(object)plantVisual == (Object)null)
{
plantVisual = ((Component)this).GetComponentInChildren<TobaccoPlantVisual>(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<ShipItem>();
}
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<Good>();
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<ShipItem> list = new List<ShipItem>(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<GameObject>(val, position, rotation);
ShipItem component = val2.GetComponent<ShipItem>();
SaveablePrefab component2 = val2.GetComponent<SaveablePrefab>();
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<SaveablePrefab>();
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<Collider>();
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<SaveablePrefab>();
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<string> InfoSink;
public static Action<string> WarningSink;
public static Action<string> 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<TobaccoPlantPotState>();
if ((Object)(object)component != (Object)null)
{
component.SyncFromSavedState();
}
RackOnlyDrying component2 = ((Component)item).GetComponent<RackOnlyDrying>();
if ((Object)(object)component2 != (Object)null)
{
component2.SyncFromSavedState();
}
DriedTobaccoLeafState component3 = ((Component)item).GetComponent<DriedTobaccoLeafState>();
if ((Object)(object)component3 != (Object)null)
{
component3.SyncFromSavedState();
}
CigarRuntimeState component4 = ((Component)item).GetComponent<CigarRuntimeState>();
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<SaveablePrefab>();
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;
}
}
}