using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HeatCooking.Core;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HeatCooking")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fbc75cb5c10e1fc8becd1288c3855066536c08fd")]
[assembly: AssemblyProduct("HeatCooking")]
[assembly: AssemblyTitle("HeatCooking")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 HeatCooking
{
[BepInPlugin("jill920.heatcooking", "Heat Cooking", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
public static ManualLogSource Log;
public static ConfigEntry<bool> DebugLogging;
public static ConfigEntry<float> CookSpeedMultiplier;
public static ConfigEntry<bool> CookHeldItems;
public static ConfigEntry<bool> CookBackpackItems;
public static ConfigEntry<float> MinimumCookSpeed;
private Harmony _harmony;
private bool _managerCreated = false;
private void Awake()
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Enable detailed debug logging");
CookSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CookSpeedMultiplier", 10f, new ConfigDescription("Multiplier for cooking speed", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
CookHeldItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CookHeldItems", false, "Whether held items should also be cooked");
CookBackpackItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CookBackpackItems", false, "Whether items inside backpacks should also be cooked");
MinimumCookSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MinimumCookSpeed", 0.01f, new ConfigDescription("Minimum cooking speed", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 1f), Array.Empty<object>()));
_harmony = new Harmony("jill920.heatcooking");
_harmony.PatchAll();
Log.LogInfo((object)"========================================");
Log.LogInfo((object)"[HeatCooking] LOADED v1.0.0");
Log.LogInfo((object)$" CookSpeedMultiplier: {CookSpeedMultiplier.Value}");
Log.LogInfo((object)$" CookHeldItems: {CookHeldItems.Value}");
Log.LogInfo((object)$" CookBackpackItems: {CookBackpackItems.Value}");
Log.LogInfo((object)$" MinimumCookSpeed: {MinimumCookSpeed.Value}");
Log.LogInfo((object)"========================================");
}
private void Update()
{
//IL_001b: 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_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
if (_managerCreated || !PhotonNetwork.IsConnected)
{
return;
}
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
if (name.StartsWith("Level"))
{
_managerCreated = true;
if (PhotonNetwork.IsMasterClient)
{
GameObject val = new GameObject("HeatCookingManager");
val.AddComponent<HeatCookingManager>();
LogDebug("HeatCookingManager created (host)");
}
else
{
LogDebug("HeatCookingManager: Not host");
}
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
internal static void LogDebug(string message)
{
if (DebugLogging.Value && Log != null)
{
Log.LogInfo((object)("[DEBUG] " + message));
}
}
internal static void LogInfo(string message)
{
if (Log != null)
{
Log.LogInfo((object)("[INFO] " + message));
}
}
internal static void LogWarning(string message)
{
if (Log != null)
{
Log.LogWarning((object)("[WARN] " + message));
}
}
}
}
namespace HeatCooking.Patches
{
[HarmonyPatch]
internal static class Campfire_CookPatch
{
[HarmonyPatch(typeof(ItemCooking), "FinishCooking")]
[HarmonyPrefix]
private static void Prefix_FinishCooking(ItemCooking __instance)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
Item val = ((ItemComponent)(__instance?)).item;
if (!((Object)(object)val == (Object)null))
{
Character trueHolderCharacter = val.trueHolderCharacter;
string text = (((Object)(object)trueHolderCharacter != (Object)null) ? trueHolderCharacter.characterName : "None");
object[] obj = new object[4]
{
val.UIData?.itemName ?? "Unknown",
text,
val.itemState,
null
};
PhotonView photonView = ((MonoBehaviourPun)val).photonView;
obj[3] = ((photonView != null) ? new int?(photonView.ViewID) : ((int?)null));
Plugin.LogDebug(string.Format("\ud83d\udd25\ud83d\udd25\ud83d\udd25 FinishCooking called on {0} (holder: {1}, state: {2}, photonView: {3})", obj));
}
}
[HarmonyPatch(typeof(ItemCooking), "EnableCookingSmokeRPC")]
[HarmonyPrefix]
private static void Prefix_EnableCookingSmokeRPC(ItemCooking __instance, bool active)
{
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
Item val = ((ItemComponent)(__instance?)).item;
if (!((Object)(object)val == (Object)null))
{
Character trueHolderCharacter = val.trueHolderCharacter;
string text = (((Object)(object)trueHolderCharacter != (Object)null) ? trueHolderCharacter.characterName : "None");
Plugin.LogDebug(string.Format("\ud83d\udca8\ud83d\udca8\ud83d\udca8 EnableCookingSmokeRPC called: active={0} on {1} (holder: {2}, state: {3})", active, val.UIData?.itemName ?? "Unknown", text, val.itemState));
}
}
[HarmonyPatch(typeof(ItemCooking), "FinishCookingRPC")]
[HarmonyPrefix]
private static void Prefix_FinishCookingRPC(ItemCooking __instance)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
Item val = ((ItemComponent)(__instance?)).item;
if (!((Object)(object)val == (Object)null))
{
Character trueHolderCharacter = val.trueHolderCharacter;
string text = (((Object)(object)trueHolderCharacter != (Object)null) ? trueHolderCharacter.characterName : "None");
object[] obj = new object[4]
{
val.UIData?.itemName ?? "Unknown",
text,
val.itemState,
null
};
PhotonView photonView = ((MonoBehaviourPun)val).photonView;
obj[3] = ((photonView != null) ? new int?(photonView.ViewID) : ((int?)null));
Plugin.LogDebug(string.Format("\ud83d\udce1\ud83d\udce1\ud83d\udce1 FinishCookingRPC called on {0} (holder: {1}, state: {2}, photonView: {3})", obj));
}
}
[HarmonyPatch(typeof(Item), "SetCookedAmountRPC")]
[HarmonyPrefix]
private static void Prefix_SetCookedAmountRPC(Item __instance, int amount)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)__instance == (Object)null))
{
Character trueHolderCharacter = __instance.trueHolderCharacter;
string text = (((Object)(object)trueHolderCharacter != (Object)null) ? trueHolderCharacter.characterName : "None");
object[] obj = new object[5]
{
amount,
__instance.UIData?.itemName ?? "Unknown",
text,
__instance.itemState,
null
};
PhotonView photonView = ((MonoBehaviourPun)__instance).photonView;
obj[4] = ((photonView != null) ? new int?(photonView.ViewID) : ((int?)null));
Plugin.LogDebug(string.Format("\ud83c\udf73\ud83c\udf73\ud83c\udf73 SetCookedAmountRPC called: amount={0} on {1} (holder: {2}, state: {3}, photonView: {4})", obj));
}
}
[HarmonyPatch(typeof(ItemCooking), "UpdateCookedBehavior")]
[HarmonyPostfix]
private static void Postfix_UpdateCookedBehavior(ItemCooking __instance)
{
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
Item val = ((ItemComponent)(__instance?)).item;
if (!((Object)(object)val == (Object)null))
{
IntItemData data = val.GetData<IntItemData>((DataEntryKey)1);
if (data != null && data.Value > 0)
{
Character trueHolderCharacter = val.trueHolderCharacter;
string text = (((Object)(object)trueHolderCharacter != (Object)null) ? trueHolderCharacter.characterName : "None");
Plugin.LogDebug(string.Format("\ud83d\udd04 UpdateCookedBehavior: {0} now cooked to level {1} (holder: {2}, state: {3})", val.UIData?.itemName ?? "Unknown", data.Value, text, val.itemState));
}
}
}
}
[HarmonyPatch(typeof(CharacterItems), "EquipSlotRpc")]
internal static class EquipSlotRpcPatch
{
private static FieldInfo _characterField;
private static FieldInfo _currentSelectedSlotField;
static EquipSlotRpcPatch()
{
_characterField = typeof(CharacterItems).GetField("character", BindingFlags.Instance | BindingFlags.NonPublic);
_currentSelectedSlotField = typeof(CharacterItems).GetField("currentSelectedSlot", BindingFlags.Instance | BindingFlags.NonPublic);
}
[HarmonyPostfix]
private static void Postfix(CharacterItems __instance, int slotID, int objectViewID)
{
//IL_004a: 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_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: 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_00b9: Invalid comparison between Unknown and I4
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
if (!PhotonNetwork.IsMasterClient)
{
return;
}
Character val = null;
if (_characterField != null)
{
object? value = _characterField.GetValue(__instance);
val = (Character)((value is Character) ? value : null);
}
if ((Object)(object)val == (Object)null)
{
return;
}
Optionable<byte> val2 = Optionable<byte>.None;
if (_currentSelectedSlotField != null)
{
val2 = (Optionable<byte>)_currentSelectedSlotField.GetValue(__instance);
}
Item val3 = null;
foreach (Item aLL_ACTIVE_ITEM in Item.ALL_ACTIVE_ITEMS)
{
if ((Object)(object)aLL_ACTIVE_ITEM != (Object)null && ClassExtensionsMethods.UnityObjectExists<Item>(aLL_ACTIVE_ITEM) && (Object)(object)aLL_ACTIVE_ITEM.trueHolderCharacter == (Object)(object)val && (int)aLL_ACTIVE_ITEM.itemState == 1)
{
val3 = aLL_ACTIVE_ITEM;
break;
}
}
if ((Object)(object)val3 != (Object)null)
{
HeldItemTracker.SetHeldItem(val, val3);
Item heldItem = HeldItemTracker.GetHeldItem(val);
if ((Object)(object)heldItem != (Object)(object)val3)
{
Plugin.LogDebug(string.Format("\ud83d\udce6 Held item: {0} -> {1} (slot: {2})", val.characterName, val3.UIData?.itemName ?? "Unknown", val2));
}
}
else
{
HeldItemTracker.SetHeldItem(val, null);
Plugin.LogDebug($"\ud83d\udc50 {val.characterName} has empty hands (slot: {val2})");
}
}
}
[HarmonyPatch(typeof(StatusEmitter), "Update")]
internal static class StatusEmitter_UpdatePatch
{
private static HashSet<int> _loggedEmitters = new HashSet<int>();
[HarmonyPostfix]
private static void Postfix(StatusEmitter __instance)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Invalid comparison between Unknown and I4
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.DebugLogging.Value || (int)__instance.statusType != 8)
{
return;
}
int instanceID = ((Object)__instance).GetInstanceID();
if (_loggedEmitters.Contains(instanceID))
{
return;
}
bool flag = false;
MethodInfo method = typeof(StatusEmitter).GetMethod("InRange", BindingFlags.Instance | BindingFlags.NonPublic);
if (method != null)
{
try
{
flag = (bool)method.Invoke(__instance, null);
}
catch
{
}
}
if (flag)
{
_loggedEmitters.Add(instanceID);
Plugin.LogDebug($"Hot emitter active: {((Object)__instance).name}, amount: {__instance.amount}, radius: {__instance.radius}, pos: {((Component)__instance).transform.position:F2}");
}
}
}
}
namespace HeatCooking.Core
{
public class CookingTracker
{
private Dictionary<Item, float> _itemCookTime = new Dictionary<Item, float>();
private List<Item> _itemsToRemove = new List<Item>();
private HashSet<Item> _cookingItems = new HashSet<Item>();
private Dictionary<int, float> _savedProgress = new Dictionary<int, float>();
public int Count => _itemCookTime.Count;
public void Update(float deltaTime)
{
Cleanup();
}
public void Cleanup()
{
_itemsToRemove.Clear();
foreach (KeyValuePair<Item, float> item in _itemCookTime)
{
if ((Object)(object)item.Key == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Item>(item.Key))
{
_itemsToRemove.Add(item.Key);
_cookingItems.Remove(item.Key);
}
}
foreach (Item item2 in _itemsToRemove)
{
_itemCookTime.Remove(item2);
}
}
public bool IsTracking(Item item)
{
return _itemCookTime.ContainsKey(item);
}
public float GetProgress(Item item)
{
float value;
return _itemCookTime.TryGetValue(item, out value) ? value : 0f;
}
public void AddTime(Item item, float time)
{
if ((Object)(object)item == (Object)null)
{
return;
}
float num = 0f;
if (_savedProgress.TryGetValue(((Object)item).GetInstanceID(), out var value))
{
num = value;
if (!_itemCookTime.ContainsKey(item))
{
_itemCookTime[item] = value;
Plugin.LogDebug(string.Format("\ud83d\udd04 Restored cooking progress for {0}: {1:F2}", item.UIData?.itemName ?? "Unknown", value));
}
}
if (!_itemCookTime.ContainsKey(item))
{
_itemCookTime[item] = 0f;
}
num = _itemCookTime[item];
_itemCookTime[item] += time;
_savedProgress[((Object)item).GetInstanceID()] = _itemCookTime[item];
if (num <= 0f && _itemCookTime[item] > 0f)
{
_cookingItems.Add(item);
StartCookingSmoke(item);
}
}
public bool IsComplete(Item item)
{
float value;
return _itemCookTime.TryGetValue(item, out value) && value >= 1f;
}
public void Reset(Item item)
{
if (!((Object)(object)item == (Object)null))
{
_itemCookTime.Remove(item);
_cookingItems.Remove(item);
_savedProgress.Remove(((Object)item).GetInstanceID());
StopCookingSmoke(item);
}
}
public void Remove(Item item)
{
if (!((Object)(object)item == (Object)null))
{
if (_itemCookTime.TryGetValue(item, out var value))
{
_savedProgress[((Object)item).GetInstanceID()] = value;
Plugin.LogDebug(string.Format("\ud83d\udcbe Saved cooking progress for {0}: {1:F2}", item.UIData?.itemName ?? "Unknown", value));
}
_itemCookTime.Remove(item);
_cookingItems.Remove(item);
StopCookingSmoke(item);
}
}
public bool TryGet(Item item, out float time)
{
return _itemCookTime.TryGetValue(item, out time);
}
public bool IsCooking(Item item)
{
return _cookingItems.Contains(item);
}
private void StartCookingSmoke(Item item)
{
if (!((Object)(object)item == (Object)null))
{
ItemCooking component = ((Component)item).GetComponent<ItemCooking>();
if ((Object)(object)component != (Object)null && (Object)(object)((MonoBehaviourPun)component).photonView != (Object)null)
{
((MonoBehaviourPun)component).photonView.RPC("EnableCookingSmokeRPC", (RpcTarget)0, new object[1] { true });
Plugin.LogDebug("\ud83d\udca8 Started cooking smoke for " + (item.UIData?.itemName ?? "Unknown"));
}
}
}
private void StopCookingSmoke(Item item)
{
if (!((Object)(object)item == (Object)null))
{
ItemCooking component = ((Component)item).GetComponent<ItemCooking>();
if ((Object)(object)component != (Object)null && (Object)(object)((MonoBehaviourPun)component).photonView != (Object)null)
{
((MonoBehaviourPun)component).photonView.RPC("EnableCookingSmokeRPC", (RpcTarget)0, new object[1] { false });
Plugin.LogDebug("\ud83d\udca8 Stopped cooking smoke for " + (item.UIData?.itemName ?? "Unknown"));
}
}
}
public void StopAllSmoke()
{
foreach (Item cookingItem in _cookingItems)
{
if ((Object)(object)cookingItem != (Object)null && ClassExtensionsMethods.UnityObjectExists<Item>(cookingItem))
{
ItemCooking component = ((Component)cookingItem).GetComponent<ItemCooking>();
if ((Object)(object)component != (Object)null && (Object)(object)((MonoBehaviourPun)component).photonView != (Object)null)
{
((MonoBehaviourPun)component).photonView.RPC("EnableCookingSmokeRPC", (RpcTarget)0, new object[1] { false });
}
}
}
_cookingItems.Clear();
}
public void UpdateSmokeForItem(Item item)
{
if (!((Object)(object)item == (Object)null))
{
bool flag = IsCooking(item);
float progress = GetProgress(item);
bool flag2 = progress > 0f && progress < 1f;
if (flag2 && !flag)
{
_cookingItems.Add(item);
StartCookingSmoke(item);
}
else if (!flag2 && flag)
{
_cookingItems.Remove(item);
StopCookingSmoke(item);
}
}
}
}
public class EmitterScanner
{
private List<StatusEmitter> _cachedEmitters = new List<StatusEmitter>();
private HashSet<string> _loggedEmitterIds = new HashSet<string>();
private bool _initialScanDone = false;
private List<StatusEmitter> _allFoundEmitters = new List<StatusEmitter>();
public int TotalCached => _cachedEmitters.Count;
public int ActiveCount => GetActiveEmitters().Count;
public List<StatusEmitter> GetActiveEmitters()
{
List<StatusEmitter> list = new List<StatusEmitter>();
foreach (StatusEmitter cachedEmitter in _cachedEmitters)
{
if ((Object)(object)cachedEmitter != (Object)null && ((Component)cachedEmitter).gameObject.activeInHierarchy)
{
list.Add(cachedEmitter);
}
}
return list;
}
public void Scan()
{
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Invalid comparison between Unknown and I4
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_0461: Unknown result type (might be due to invalid IL or missing references)
//IL_0467: Invalid comparison between Unknown and I4
//IL_0494: Unknown result type (might be due to invalid IL or missing references)
//IL_0499: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
StatusEmitter[] array = Object.FindObjectsOfType<StatusEmitter>();
StatusEmitter[] array2 = Resources.FindObjectsOfTypeAll<StatusEmitter>();
List<StatusEmitter> list = new List<StatusEmitter>();
HashSet<int> hashSet = new HashSet<int>();
StatusEmitter[] array3 = array;
foreach (StatusEmitter val in array3)
{
if ((Object)(object)val != (Object)null && !hashSet.Contains(((Object)val).GetInstanceID()))
{
hashSet.Add(((Object)val).GetInstanceID());
list.Add(val);
}
}
StatusEmitter[] array4 = array2;
foreach (StatusEmitter val2 in array4)
{
if ((Object)(object)val2 != (Object)null && !hashSet.Contains(((Object)val2).GetInstanceID()))
{
hashSet.Add(((Object)val2).GetInstanceID());
list.Add(val2);
}
}
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
bool flag = !_initialScanDone;
Scene scene;
foreach (StatusEmitter item in list)
{
if ((Object)(object)item == (Object)null || (int)item.statusType != 8)
{
continue;
}
num++;
scene = ((Component)item).gameObject.scene;
string name = ((Scene)(ref scene)).name;
bool activeInHierarchy = ((Component)item).gameObject.activeInHierarchy;
float amount = item.amount;
Vector3 position = ((Component)item).transform.position;
string name2 = ((Object)item).name;
bool flag2 = activeInHierarchy || amount > 0.1f || name.StartsWith("Level");
if (flag && flag2)
{
Plugin.LogDebug($"FOUND: {name2} | pos: {position:F2} | active: {activeInHierarchy} | amount: {amount:F2} | scene: '{name}'");
}
if (!name.StartsWith("Level") && !string.IsNullOrEmpty(name))
{
num3++;
continue;
}
if (string.IsNullOrEmpty(name) && !activeInHierarchy)
{
num3++;
continue;
}
if (amount <= 0f)
{
num4++;
continue;
}
bool flag3 = false;
foreach (StatusEmitter cachedEmitter in _cachedEmitters)
{
if ((Object)(object)cachedEmitter == (Object)(object)item)
{
flag3 = true;
break;
}
}
if (!flag3)
{
_cachedEmitters.Add(item);
num2++;
Plugin.LogDebug($"✅ ADDED: {name2} at {position:F2}, active: {activeInHierarchy}, amount: {amount:F2}, scene: '{name}'");
}
}
if (!_initialScanDone)
{
_initialScanDone = true;
int activeCount = ActiveCount;
Plugin.LogInfo($"First scan: found {num} hot emitters, added {num2}, cached: {_cachedEmitters.Count}, active: {activeCount}");
Plugin.LogInfo($" Skipped: scene={num3}, amount={num4}");
}
else if (num2 > 0)
{
Plugin.LogInfo($"Scan: added {num2} new emitters, cached: {_cachedEmitters.Count}, active: {ActiveCount}");
}
if (num <= 0 || _cachedEmitters.Count != 0 || Time.frameCount % 120 != 0)
{
return;
}
Plugin.LogWarning($"Found {num} emitters but none were cached! Check scene names and amounts.");
int num5 = 0;
foreach (StatusEmitter item2 in list)
{
if (!((Object)(object)item2 == (Object)null))
{
if (num5 >= 5)
{
break;
}
if ((int)item2.statusType == 8)
{
num5++;
object[] obj = new object[4]
{
((Object)item2).name,
null,
null,
null
};
scene = ((Component)item2).gameObject.scene;
obj[1] = ((Scene)(ref scene)).name;
obj[2] = ((Component)item2).gameObject.activeInHierarchy;
obj[3] = item2.amount;
Plugin.LogDebug(string.Format(" Example: {0} | scene: '{1}' | active: {2} | amount: {3}", obj));
}
}
}
}
public void LogActiveEmitters()
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
List<StatusEmitter> activeEmitters = GetActiveEmitters();
if (activeEmitters.Count <= 0 || Time.frameCount % 60 != 0)
{
return;
}
Plugin.LogDebug($"Active emitters ({activeEmitters.Count}):");
foreach (StatusEmitter item in activeEmitters)
{
Plugin.LogDebug($" - {((Object)item).name} at {((Component)item).transform.position:F2}, radius: {item.radius}, amount: {item.amount}");
}
}
public void Clear()
{
_cachedEmitters.Clear();
_loggedEmitterIds.Clear();
_allFoundEmitters.Clear();
_initialScanDone = false;
}
}
public class HeatCookingManager : MonoBehaviour
{
private EmitterScanner _scanner;
private CookingTracker _tracker;
private ItemCooker _cooker;
private float _cookTimer = 0f;
private float _scanTimer = 0f;
private const float COOK_INTERVAL = 0.5f;
private const float SCAN_INTERVAL = 1f;
private int _logCounter = 0;
private void Start()
{
_scanner = new EmitterScanner();
_tracker = new CookingTracker();
_cooker = new ItemCooker(_tracker);
_scanner.Scan();
}
private void Update()
{
if (PhotonNetwork.IsMasterClient)
{
_scanTimer += Time.deltaTime;
if (_scanTimer > 1f)
{
_scanTimer = 0f;
_scanner.Scan();
}
_cookTimer += Time.deltaTime;
if (_cookTimer > 0.5f)
{
_cookTimer = 0f;
CookItems();
}
}
}
private void CookItems()
{
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Invalid comparison between Unknown and I4
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Invalid comparison between Unknown and I4
_tracker.Cleanup();
List<StatusEmitter> activeEmitters = _scanner.GetActiveEmitters();
HashSet<Item> processedItems = new HashSet<Item>();
if (Time.frameCount % 60 == 0)
{
_scanner.LogActiveEmitters();
}
if (Time.frameCount % 30 == 0)
{
int count = Item.ALL_ACTIVE_ITEMS.Count;
Plugin.LogDebug($"=== ALL_ACTIVE_ITEMS ({count} items), Active emitters: {activeEmitters.Count}/{_scanner.TotalCached} ===");
}
if (activeEmitters.Count == 0)
{
return;
}
int itemsInHeat = 0;
int itemsCooking = 0;
int itemsCompleted = 0;
foreach (Item aLL_ACTIVE_ITEM in Item.ALL_ACTIVE_ITEMS)
{
if (!((Object)(object)aLL_ACTIVE_ITEM == (Object)null) && ClassExtensionsMethods.UnityObjectExists<Item>(aLL_ACTIVE_ITEM) && (int)aLL_ACTIVE_ITEM.itemState == 0 && _cooker.ShouldCookItem(aLL_ACTIVE_ITEM))
{
float num = ProcessItemInHeatZone(aLL_ACTIVE_ITEM, activeEmitters, ref itemsInHeat, ref itemsCooking, processedItems);
if (num >= 1f)
{
itemsCompleted++;
}
}
}
if (Plugin.CookBackpackItems.Value)
{
foreach (Item aLL_ACTIVE_ITEM2 in Item.ALL_ACTIVE_ITEMS)
{
if (!((Object)(object)aLL_ACTIVE_ITEM2 == (Object)null) && ClassExtensionsMethods.UnityObjectExists<Item>(aLL_ACTIVE_ITEM2) && (int)aLL_ACTIVE_ITEM2.itemState == 2 && _cooker.ShouldCookItem(aLL_ACTIVE_ITEM2))
{
float num2 = ProcessItemInHeatZone(aLL_ACTIVE_ITEM2, activeEmitters, ref itemsInHeat, ref itemsCooking, processedItems);
if (num2 >= 1f)
{
itemsCompleted++;
}
}
}
}
if (Plugin.CookHeldItems.Value)
{
CookHeldItems(activeEmitters, processedItems, ref itemsCompleted);
}
_logCounter++;
if (_logCounter % 10 == 0 && (itemsInHeat > 0 || itemsCooking > 0))
{
Plugin.LogDebug($"Cooking summary: {itemsCooking} cooking, {itemsInHeat} in heat, {itemsCompleted} completed, {_tracker.Count} tracked");
}
}
private void CookHeldItems(List<StatusEmitter> activeEmitters, HashSet<Item> processedItems, ref int itemsCompleted)
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: 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_0103: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.CookHeldItems.Value || activeEmitters.Count == 0)
{
return;
}
HeldItemTracker.Cleanup();
int num = 0;
int num2 = 0;
foreach (KeyValuePair<Character, Item> allHeldItem in HeldItemTracker.GetAllHeldItems())
{
Character key = allHeldItem.Key;
Item value = allHeldItem.Value;
if ((Object)(object)key == (Object)null || (Object)(object)value == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Item>(value) || !_cooker.ShouldCookItem(value) || processedItems.Contains(value))
{
continue;
}
Vector3 center = key.Center;
bool flag = false;
float num3 = float.MaxValue;
float num4 = 0f;
foreach (StatusEmitter activeEmitter in activeEmitters)
{
if ((Object)(object)activeEmitter == (Object)null)
{
continue;
}
float num5 = Vector3.Distance(center, ((Component)activeEmitter).transform.position);
float num6 = activeEmitter.radius + activeEmitter.outerFade;
if (num5 <= num6)
{
flag = true;
if (num5 < num3)
{
num3 = num5;
num4 = _cooker.GetCookSpeed(value, activeEmitter);
}
}
}
if (flag)
{
processedItems.Add(value);
num++;
if (num4 > 0.0001f)
{
float num7 = _cooker.CookItem(value, num4, 0.5f);
if (num7 >= 1f)
{
itemsCompleted++;
Plugin.LogDebug("✅ Client held item completed: " + (value.UIData?.itemName ?? "Unknown") + " held by " + key.characterName);
}
num2++;
}
}
else if (_tracker.IsTracking(value))
{
_tracker.Remove(value);
}
}
if (num > 0 || num2 > 0)
{
Plugin.LogDebug($"\ud83c\udf73 Client held items: {num2} cooking, {num} in heat");
}
}
private float ProcessItemInHeatZone(Item item, List<StatusEmitter> activeEmitters, ref int itemsInHeat, ref int itemsCooking, HashSet<Item> processedItems)
{
//IL_0030: 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_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
if (processedItems.Contains(item))
{
return 0f;
}
bool flag = false;
float num = float.MaxValue;
float num2 = 0f;
Vector3 itemPosition = _cooker.GetItemPosition(item);
foreach (StatusEmitter activeEmitter in activeEmitters)
{
if (!((Object)(object)activeEmitter == (Object)null) && _cooker.IsItemInHeatZone(item, activeEmitter))
{
flag = true;
float num3 = Vector3.Distance(itemPosition, ((Component)activeEmitter).transform.position);
if (num3 < num)
{
num = num3;
num2 = _cooker.GetCookSpeed(item, activeEmitter);
}
}
}
if (flag)
{
processedItems.Add(item);
itemsInHeat++;
if (num2 > 0.0001f)
{
float num4 = _cooker.CookItem(item, num2, 0.5f);
if (num4 >= 1f)
{
itemsCooking++;
}
return num4;
}
}
else if (_tracker.IsTracking(item))
{
_tracker.Remove(item);
}
return 0f;
}
private void OnDestroy()
{
_scanner?.Clear();
_tracker?.StopAllSmoke();
}
}
public static class HeldItemTracker
{
private static Dictionary<int, Item> _heldItems = new Dictionary<int, Item>();
private static Dictionary<int, int> _heldItemViewIDs = new Dictionary<int, int>();
private static Dictionary<int, bool> _hasEmptyHands = new Dictionary<int, bool>();
public static int Count => _heldItems.Count;
public static void SetHeldItem(Character character, Item item)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Invalid comparison between Unknown and I4
if ((Object)(object)character == (Object)null)
{
return;
}
int instanceID = ((Object)character).GetInstanceID();
Item value;
if ((Object)(object)item == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Item>(item))
{
bool flag = false;
foreach (Item aLL_ACTIVE_ITEM in Item.ALL_ACTIVE_ITEMS)
{
if ((Object)(object)aLL_ACTIVE_ITEM != (Object)null && ClassExtensionsMethods.UnityObjectExists<Item>(aLL_ACTIVE_ITEM) && (Object)(object)aLL_ACTIVE_ITEM.trueHolderCharacter == (Object)(object)character && (int)aLL_ACTIVE_ITEM.itemState == 1)
{
flag = true;
_heldItems[instanceID] = aLL_ACTIVE_ITEM;
Dictionary<int, int> heldItemViewIDs = _heldItemViewIDs;
PhotonView photonView = ((MonoBehaviourPun)aLL_ACTIVE_ITEM).photonView;
heldItemViewIDs[instanceID] = ((photonView != null) ? photonView.ViewID : (-1));
_hasEmptyHands[instanceID] = false;
Plugin.LogDebug("\ud83d\udd0d Corrected held item for " + character.characterName + ": " + (aLL_ACTIVE_ITEM.UIData?.itemName ?? "Unknown"));
return;
}
}
if (!flag)
{
_heldItems.Remove(instanceID);
_heldItemViewIDs.Remove(instanceID);
_hasEmptyHands[instanceID] = true;
}
}
else if (_heldItems.TryGetValue(instanceID, out value) && (Object)(object)value != (Object)null && ((Object)value).GetInstanceID() == ((Object)item).GetInstanceID())
{
if ((Object)(object)((MonoBehaviourPun)item).photonView != (Object)null)
{
_heldItemViewIDs[instanceID] = ((MonoBehaviourPun)item).photonView.ViewID;
}
_hasEmptyHands[instanceID] = false;
}
else
{
_heldItems[instanceID] = item;
Dictionary<int, int> heldItemViewIDs2 = _heldItemViewIDs;
PhotonView photonView2 = ((MonoBehaviourPun)item).photonView;
heldItemViewIDs2[instanceID] = ((photonView2 != null) ? photonView2.ViewID : (-1));
_hasEmptyHands[instanceID] = false;
Plugin.LogDebug(string.Format("\ud83d\udce6 Held item tracked: {0} -> {1} (ViewID: {2})", character.characterName, item.UIData?.itemName ?? "Unknown", _heldItemViewIDs[instanceID]));
}
}
public static Item GetHeldItem(Character character)
{
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Invalid comparison between Unknown and I4
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Invalid comparison between Unknown and I4
if ((Object)(object)character == (Object)null)
{
return null;
}
int instanceID = ((Object)character).GetInstanceID();
if (_hasEmptyHands.TryGetValue(instanceID, out var value) && value)
{
foreach (Item aLL_ACTIVE_ITEM in Item.ALL_ACTIVE_ITEMS)
{
if ((Object)(object)aLL_ACTIVE_ITEM != (Object)null && ClassExtensionsMethods.UnityObjectExists<Item>(aLL_ACTIVE_ITEM) && (Object)(object)aLL_ACTIVE_ITEM.trueHolderCharacter == (Object)(object)character && (int)aLL_ACTIVE_ITEM.itemState == 1)
{
_heldItems[instanceID] = aLL_ACTIVE_ITEM;
Dictionary<int, int> heldItemViewIDs = _heldItemViewIDs;
PhotonView photonView = ((MonoBehaviourPun)aLL_ACTIVE_ITEM).photonView;
heldItemViewIDs[instanceID] = ((photonView != null) ? photonView.ViewID : (-1));
_hasEmptyHands[instanceID] = false;
return aLL_ACTIVE_ITEM;
}
}
return null;
}
if (_heldItems.TryGetValue(instanceID, out var value2))
{
if ((Object)(object)value2 == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Item>(value2) || (Object)(object)value2.trueHolderCharacter != (Object)(object)character || (int)value2.itemState != 1)
{
_heldItems.Remove(instanceID);
_heldItemViewIDs.Remove(instanceID);
_hasEmptyHands[instanceID] = true;
return null;
}
return value2;
}
return null;
}
public static bool HasHeldItem(Character character)
{
if ((Object)(object)character == (Object)null)
{
return false;
}
return (Object)(object)GetHeldItem(character) != (Object)null;
}
public static IEnumerable<KeyValuePair<Character, Item>> GetAllHeldItems()
{
Cleanup();
foreach (KeyValuePair<int, Item> kvp in _heldItems)
{
Character character = null;
foreach (Character c in Character.AllCharacters)
{
if ((Object)(object)c != (Object)null && ((Object)c).GetInstanceID() == kvp.Key)
{
character = c;
break;
}
}
if ((Object)(object)character != (Object)null && (Object)(object)kvp.Value != (Object)null && ClassExtensionsMethods.UnityObjectExists<Item>(kvp.Value) && (Object)(object)kvp.Value.trueHolderCharacter == (Object)(object)character && (int)kvp.Value.itemState == 1)
{
yield return new KeyValuePair<Character, Item>(character, kvp.Value);
}
}
}
public static void Cleanup()
{
List<int> list = new List<int>();
foreach (KeyValuePair<int, Item> heldItem in _heldItems)
{
if ((Object)(object)heldItem.Value == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Item>(heldItem.Value))
{
list.Add(heldItem.Key);
continue;
}
bool flag = false;
foreach (Character allCharacter in Character.AllCharacters)
{
if ((Object)(object)allCharacter != (Object)null && ((Object)allCharacter).GetInstanceID() == heldItem.Key)
{
flag = true;
break;
}
}
if (!flag)
{
list.Add(heldItem.Key);
}
}
foreach (int item in list)
{
_heldItems.Remove(item);
_heldItemViewIDs.Remove(item);
_hasEmptyHands.Remove(item);
}
}
public static void Clear()
{
_heldItems.Clear();
_heldItemViewIDs.Clear();
_hasEmptyHands.Clear();
Plugin.LogDebug("\ud83e\uddf9 All held items cleared");
}
}
public class ItemCooker
{
private CookingTracker _tracker;
public ItemCooker(CookingTracker tracker)
{
_tracker = tracker;
}
public bool ShouldCookItem(Item item)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Invalid comparison between Unknown and I4
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Invalid comparison between Unknown and I4
if ((Object)(object)item == (Object)null)
{
return false;
}
ItemCooking component = ((Component)item).GetComponent<ItemCooking>();
if ((Object)(object)component == (Object)null)
{
return false;
}
if (!component.canBeCooked)
{
return false;
}
IntItemData data = item.GetData<IntItemData>((DataEntryKey)1);
if (data != null && data.Value >= 12)
{
return false;
}
if (!Plugin.CookHeldItems.Value && (int)item.itemState == 1)
{
return false;
}
if (!Plugin.CookBackpackItems.Value && (int)item.itemState == 2)
{
return false;
}
return true;
}
public List<Item> GetBackpackItems()
{
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Invalid comparison between Unknown and I4
List<Item> list = new List<Item>();
if (!Plugin.CookBackpackItems.Value)
{
return list;
}
Backpack[] array = Object.FindObjectsByType<Backpack>((FindObjectsInactive)0, (FindObjectsSortMode)1);
Backpack[] array2 = array;
foreach (Backpack val in array2)
{
if ((Object)(object)val == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Backpack>(val))
{
continue;
}
BackpackData data = ((Item)val).GetData<BackpackData>((DataEntryKey)7);
if (data == null)
{
continue;
}
for (int j = 0; j < data.itemSlots.Length; j++)
{
ItemSlot val2 = data.itemSlots[j];
if (val2 == null || val2.IsEmpty())
{
continue;
}
Item prefab = val2.prefab;
if ((Object)(object)prefab == (Object)null)
{
continue;
}
ItemCooking component = ((Component)prefab).GetComponent<ItemCooking>();
if ((Object)(object)component == (Object)null || !component.canBeCooked)
{
continue;
}
IntItemData data2 = prefab.GetData<IntItemData>((DataEntryKey)1);
if (data2 != null && data2.Value >= 12)
{
continue;
}
Item val3 = null;
foreach (Item aLL_ACTIVE_ITEM in Item.ALL_ACTIVE_ITEMS)
{
if ((Object)(object)aLL_ACTIVE_ITEM == (Object)null || !ClassExtensionsMethods.UnityObjectExists<Item>(aLL_ACTIVE_ITEM) || aLL_ACTIVE_ITEM.itemID != prefab.itemID || (int)aLL_ACTIVE_ITEM.itemState != 2)
{
continue;
}
FieldInfo field = typeof(Item).GetField("backpackReference", BindingFlags.Instance | BindingFlags.NonPublic);
if (!(field != null))
{
continue;
}
object value = field.GetValue(aLL_ACTIVE_ITEM);
if (value == null)
{
continue;
}
Type type = value.GetType();
FieldInfo field2 = type.GetField("view");
if (field2 != null)
{
object? value2 = field2.GetValue(value);
PhotonView val4 = (PhotonView)((value2 is PhotonView) ? value2 : null);
if ((Object)(object)val4 != (Object)null && (Object)(object)((Component)val4).GetComponent<Backpack>() == (Object)(object)val)
{
val3 = aLL_ACTIVE_ITEM;
break;
}
}
}
if ((Object)(object)val3 != (Object)null)
{
list.Add(val3);
}
}
}
return list;
}
public float GetCookSpeed(Item item, StatusEmitter emitter)
{
//IL_001c: 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_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)emitter == (Object)null)
{
return 0f;
}
Vector3 itemPosition = GetItemPosition(item);
Vector3 position = ((Component)emitter).transform.position;
float num = Vector3.Distance(itemPosition, position);
float num2 = emitter.radius + emitter.outerFade;
float num3 = 1f - Mathf.Clamp01(num / num2);
if (emitter.innerFade > 0f && num < emitter.radius - emitter.innerFade)
{
num3 = 1f;
}
float num4 = Mathf.Abs(emitter.amount) * 2f;
float num5 = num4 * num3 * Plugin.CookSpeedMultiplier.Value;
if (num5 < Plugin.MinimumCookSpeed.Value)
{
num5 = Plugin.MinimumCookSpeed.Value;
}
return num5;
}
public Vector3 GetItemPosition(Item item)
{
//IL_0015: 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_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)item == (Object)null)
{
return Vector3.zero;
}
return item.Center();
}
public bool IsItemInHeatZone(Item item, StatusEmitter emitter)
{
//IL_0015: 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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)emitter == (Object)null)
{
return false;
}
Vector3 itemPosition = GetItemPosition(item);
Vector3 position = ((Component)emitter).transform.position;
float num = Vector3.Distance(itemPosition, position);
float num2 = emitter.radius + emitter.outerFade;
return num <= num2;
}
public float CookItem(Item item, float cookSpeed, float deltaTime)
{
if (!ShouldCookItem(item))
{
return 0f;
}
if (!_tracker.IsTracking(item))
{
_tracker.AddTime(item, 0f);
Plugin.LogDebug(string.Format("✅ Started cooking {0} (speed: {1:F4})", item.UIData?.itemName ?? "Unknown", cookSpeed));
}
_tracker.AddTime(item, cookSpeed * deltaTime);
_tracker.UpdateSmokeForItem(item);
float progress = _tracker.GetProgress(item);
if (progress >= 1f)
{
ApplyCookedState(item);
_tracker.Reset(item);
int cookedLevel = GetCookedLevel(item);
Plugin.LogInfo(string.Format("\ud83d\udd25 Item cooked: {0} (level: {1}/12)", item.UIData?.itemName ?? "Unknown", cookedLevel));
return 1f;
}
return progress;
}
private int GetCookedLevel(Item item)
{
return item.GetData<IntItemData>((DataEntryKey)1)?.Value ?? 0;
}
private void ApplyCookedState(Item item)
{
if ((Object)(object)item == (Object)null)
{
return;
}
ItemCooking component = ((Component)item).GetComponent<ItemCooking>();
if ((Object)(object)component == (Object)null)
{
return;
}
PhotonView photonView = ((MonoBehaviourPun)item).photonView;
if (!((Object)(object)photonView == (Object)null))
{
int num = item.GetData<IntItemData>((DataEntryKey)1)?.Value ?? 0;
if (num >= 12)
{
Plugin.LogDebug(string.Format("\ud83d\udcdd Item {0} already at max cooked amount ({1})", item.UIData?.itemName ?? "Unknown", num));
return;
}
photonView.RPC("FinishCookingRPC", (RpcTarget)0, Array.Empty<object>());
Plugin.LogDebug(string.Format("\ud83d\udce1 FinishCookingRPC called for {0} (level {1} -> {2})", item.UIData?.itemName ?? "Unknown", num, num + 1));
component.CancelCookingVisuals();
component.UpdateCookedBehavior();
}
}
}
}