Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Beeswax v1.0.5
Beeswax.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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 Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("Beeswax")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5")] [assembly: AssemblyProduct("Beeswax")] [assembly: AssemblyTitle("Beeswax")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.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 Beeswax { internal static class ApplySound { private static readonly MethodInfo CreateMethod = AccessTools.Method(typeof(EffectList), "Create", new Type[6] { typeof(Vector3), typeof(Quaternion), typeof(Transform), typeof(float), typeof(int), typeof(ZDOID) }, (Type[])null) ?? AccessTools.Method(typeof(EffectList), "Create", new Type[5] { typeof(Vector3), typeof(Quaternion), typeof(Transform), typeof(float), typeof(int) }, (Type[])null) ?? AccessTools.Method(typeof(EffectList), "Create", new Type[2] { typeof(Vector3), typeof(Quaternion) }, (Type[])null); private static EffectList _effect; internal static void PlayAt(Vector3 position) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Play(GetEffect(), position); } internal static void Play(EffectList effect, Vector3 position) { //IL_002b: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (effect == null || CreateMethod == null) { return; } try { ParameterInfo[] parameters = CreateMethod.GetParameters(); object[] parameters2 = ((parameters.Length >= 6) ? new object[6] { position, Quaternion.identity, null, 1f, -1, ZDOID.None } : ((parameters.Length < 5) ? new object[2] { position, Quaternion.identity } : new object[5] { position, Quaternion.identity, null, 1f, -1 })); CreateMethod.Invoke(effect, parameters2); } catch (Exception ex) { BeeswaxPlugin.Log.LogWarning((object)("Could not play effect: " + ex.Message)); } } private static EffectList GetEffect() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown if (_effect != null) { return _effect; } if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hoe"); EffectList val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_buildEffect; if (val != null && val.m_effectPrefabs.Length != 0) { _effect = val; return _effect; } } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab("sfx_build_hoe"); if ((Object)(object)prefab == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Could not find beeswax apply sound (sfx_build_hoe)."); return null; } EffectList val2 = new EffectList(); val2.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = prefab } }; _effect = val2; return _effect; } } internal static class BeehivePatches { [HarmonyPatch(typeof(Beehive), "UpdateBees")] private static class UpdateBeesPatch { private static void Postfix(Beehive __instance) { if (!IsHoneyBeehive(__instance)) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner() && __instance.CheckBiome() && __instance.HaveFreeSpace()) { float elapsedSeconds = GetElapsedSeconds(component); float num = component.GetZDO().GetFloat("beeswax_product", 0f); num += elapsedSeconds; float num2 = __instance.m_secPerUnit * BeeswaxConfig.GetHiveProductionSlowdown(); if (num2 > 0f && num > num2) { int num3 = (int)(num / num2); int num4 = component.GetZDO().GetInt("beeswax_count", 0); num4 = Mathf.Min(num4 + num3 * BeeswaxConfig.HivePerCycle.Value, BeeswaxConfig.HiveMaxStored.Value); component.GetZDO().Set("beeswax_count", num4); num -= (float)num3 * num2; } component.GetZDO().Set("beeswax_product", num); } } private static float GetElapsedSeconds(ZNetView nview) { DateTime time = ZNet.instance.GetTime(); long num = nview.GetZDO().GetLong("beeswax_lastTime", 0L); if (num <= 0) { nview.GetZDO().Set("beeswax_lastTime", time.Ticks); return 0f; } DateTime dateTime = new DateTime(num); nview.GetZDO().Set("beeswax_lastTime", time.Ticks); double totalSeconds = (time - dateTime).TotalSeconds; if (!(totalSeconds < 0.0)) { return (float)totalSeconds; } return 0f; } } [HarmonyPatch(typeof(Beehive), "Interact")] private static class InteractPatch { private static bool Prefix(Beehive __instance, Humanoid character, bool repeat, bool alt, ref bool __result) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!IsHoneyBeehive(__instance)) { return true; } if (repeat || !PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false)) { return true; } if (GetHoneyLevel(__instance) > 0) { return true; } if (GetStoredCount(__instance) <= 0) { return true; } ExtractMethod.Invoke(__instance, null); TryIncrementBeesHarvested(); __result = true; return false; } } [HarmonyPatch(typeof(Beehive), "RPC_Extract")] private static class ExtractPatch { private static void Postfix(Beehive __instance) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!IsHoneyBeehive(__instance)) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } int num = component.GetZDO().GetInt("beeswax_count", 0); if (num > 0) { if ((Object)(object)BeeswaxItem.Prefab == (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { BeeswaxItem.Register(ObjectDB.instance); } SpawnBeeswax(__instance, num); component.GetZDO().Set("beeswax_count", 0); if (GetHoneyLevel(__instance) <= 0) { ApplySound.Play(__instance.m_spawnEffect, __instance.m_spawnPoint.position); } } } private static void SpawnBeeswax(Beehive hive, int amount) { //IL_0014: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) int num = amount; int num2 = 0; int maxStack = BeeswaxConfig.GetMaxStack(); while (num > 0) { int num3 = Mathf.Min(num, maxStack); Vector2 val = Random.insideUnitCircle * 0.5f; Vector3 position = hive.m_spawnPoint.position + new Vector3(val.x, 0.25f * (float)num2, val.y); BeeswaxItem.Drop(num3, position, Quaternion.identity); num -= num3; num2++; } } } [HarmonyPatch(typeof(Beehive), "GetHoverText")] private static class HoverTextPatch { private static void Postfix(Beehive __instance, ref string __result) { if (!IsHoneyBeehive(__instance)) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } int num = component.GetZDO().GetInt("beeswax_count", 0); if (num <= 0) { return; } string arg = Localization.instance.Localize("$item_beeswax"); string text = $"( {arg} x {num} )"; if (GetHoneyLevel(__instance) == 0) { string text2 = Localization.instance.Localize("$piece_container_empty"); string text3 = "( " + text2 + " )"; if (__result.Contains(text3)) { __result = __result.Replace(text3, text); } else { InsertBeforeUseKey(ref __result, AlignWithFirstParen(__result, text)); } string oldValue = Localization.instance.Localize(__instance.m_checkText); string newValue = Localization.instance.Localize(__instance.m_extractText); __result = __result.Replace(oldValue, newValue); } else { InsertBeforeUseKey(ref __result, AlignWithFirstParen(__result, text)); } } private static string AlignWithFirstParen(string hover, string waxParen) { int num = hover.IndexOf('\n'); string text = ((num >= 0) ? hover.Substring(0, num) : hover); int num2 = text.IndexOf('('); if (num2 <= 0) { return waxParen; } return "<color=#00000000>" + text.Substring(0, num2) + "</color>" + waxParen; } private static void InsertBeforeUseKey(ref string result, string beeswaxAmount) { int num = result.IndexOf("[<color=yellow>"); if (num < 0) { num = result.IndexOf("$KEY_Use"); } if (num >= 0) { result = result.Insert(num, beeswaxAmount + "\n"); } else { result = result + "\n" + beeswaxAmount; } } } private static readonly MethodInfo ExtractMethod = AccessTools.Method(typeof(Beehive), "Extract", (Type[])null, (Type[])null); private static readonly MethodInfo IncrementPlayerStatMethod = AccessTools.Method(typeof(Game), "IncrementPlayerStat", new Type[3] { typeof(PlayerStatType), typeof(float), typeof(bool) }, (Type[])null) ?? AccessTools.Method(typeof(Game), "IncrementPlayerStat", new Type[2] { typeof(PlayerStatType), typeof(float) }, (Type[])null) ?? AccessTools.Method(typeof(Game), "IncrementPlayerStat", new Type[1] { typeof(PlayerStatType) }, (Type[])null); internal const string BeeswaxProductKey = "beeswax_product"; internal const string BeeswaxCountKey = "beeswax_count"; internal const string BeeswaxLastTimeKey = "beeswax_lastTime"; private static void TryIncrementBeesHarvested() { if ((Object)(object)Game.instance == (Object)null || IncrementPlayerStatMethod == null) { return; } try { ParameterInfo[] parameters = IncrementPlayerStatMethod.GetParameters(); object[] parameters2 = ((parameters.Length >= 3) ? new object[3] { (object)(PlayerStatType)76, 1f, false } : ((parameters.Length != 2) ? new object[1] { (object)(PlayerStatType)76 } : new object[2] { (object)(PlayerStatType)76, 1f })); IncrementPlayerStatMethod.Invoke(Game.instance, parameters2); } catch (Exception ex) { BeeswaxPlugin.Log.LogWarning((object)("Could not increment BeesHarvested stat: " + ex.Message)); } } private static bool IsHoneyBeehive(Beehive hive) { if ((Object)(object)hive == (Object)null) { return false; } string prefabName = Utils.GetPrefabName(((Object)((Component)hive).gameObject).name); if (prefabName.IndexOf("bird", StringComparison.OrdinalIgnoreCase) >= 0 || prefabName.IndexOf("feather", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } ItemDrop honeyItem = hive.m_honeyItem; if ((Object)(object)honeyItem == (Object)null) { return false; } if (Utils.GetPrefabName(((Object)((Component)honeyItem).gameObject).name) == "Honey") { return true; } return honeyItem.m_itemData?.m_shared?.m_name == "$item_honey"; } private static int GetHoneyLevel(Beehive hive) { ZNetView component = ((Component)hive).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return 0; } return component.GetZDO().GetInt(ZDOVars.s_level, 0); } internal static int GetStoredCount(Beehive hive) { ZNetView component = ((Component)hive).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return 0; } return component.GetZDO().GetInt("beeswax_count", 0); } } internal static class BeeswaxConfig { internal static ConfigEntry<int> MaxStack; internal static ConfigEntry<int> HiveMaxStored; internal static ConfigEntry<int> HivePerCycle; internal static ConfigEntry<float> HiveProductionSlowdown; internal static ConfigEntry<int> WildNestDropCount; internal static ConfigEntry<bool> ShowWaxedVisuals; internal static ConfigEntry<bool> ShowHoverTextWithVisuals; internal static ConfigEntry<bool> ShowWaxedLabel; internal static ConfigEntry<bool> ShowAlreadyWaxedLabel; internal static ConfigEntry<bool> ShowApplyLabel; internal static void Init(ConfigFile config) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown MaxStack = config.Bind<int>("Item", "MaxStack", 30, new ConfigDescription("Max beeswax per inventory stack.", (AcceptableValueBase)null, new object[1] { new AcceptableValueRange<int>(1, 999) })); HiveMaxStored = config.Bind<int>("Beehive", "MaxStored", 10, new ConfigDescription("Max wax stored in a player-built beehive.", (AcceptableValueBase)null, new object[1] { new AcceptableValueRange<int>(1, 999) })); HivePerCycle = config.Bind<int>("Beehive", "PerCycle", 2, new ConfigDescription("Wax produced each production cycle. 0 disables hive wax.", (AcceptableValueBase)null, new object[1] { new AcceptableValueRange<int>(0, 999) })); HiveProductionSlowdown = config.Bind<float>("Beehive", "ProductionSlowdown", 1.3f, new ConfigDescription("Multiplier on honey production time for wax. Higher = slower wax.", (AcceptableValueBase)null, new object[1] { new AcceptableValueRange<float>(0.1f, 20f) })); WildNestDropCount = config.Bind<int>("Wild Nest", "DropCount", 1, new ConfigDescription("Wax dropped when breaking a wild beehive. 0 disables the drop.", (AcceptableValueBase)null, new object[1] { new AcceptableValueRange<int>(0, 99) })); ShowWaxedVisuals = config.Bind<bool>("Waxed Visuals", "ShowWaxedVisuals", true, "Show the warm glossy look on waxed wood. When off, hover text labels are shown instead."); ShowWaxedVisuals.SettingChanged += delegate { StructureVisuals.RefreshAll(); }; ShowHoverTextWithVisuals = config.Bind<bool>("Waxed Visuals", "ShowHoverTextWithVisuals", false, "Also show hover text labels while waxed visuals are on. Off by default."); ShowWaxedLabel = config.Bind<bool>("Hover Text", "ShowWaxedLabel", false, "Show 'Waxed' when looking at a waxed piece without beeswax equipped. Only when hover text is allowed."); ShowAlreadyWaxedLabel = config.Bind<bool>("Hover Text", "ShowAlreadyWaxedLabel", true, "Show 'Already waxed' when holding beeswax and looking at a waxed piece. Only when hover text is allowed."); ShowApplyLabel = config.Bind<bool>("Hover Text", "ShowApplyLabel", false, "Show the left-click apply hint when holding beeswax and looking at un-waxed wood. Only when hover text is allowed."); } internal static bool IsHoverTextAllowed() { if (ShowWaxedVisuals.Value) { return ShowHoverTextWithVisuals.Value; } return true; } internal static int GetMaxStack() { return Mathf.Max(1, MaxStack.Value); } internal static float GetHiveProductionSlowdown() { return Mathf.Max(0.1f, HiveProductionSlowdown.Value); } } internal static class BeeswaxItem { [HarmonyPatch(typeof(Humanoid), "EquipItem")] private static class EquipItemPatch { private static void Prefix(ItemData item) { EnsureItemConfigured(item); } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] private static class TooltipPatch { private static void Postfix(ItemData item, ref string __result) { if (IsBeeswaxItem(item)) { __result = __result.Replace("\n$item_twohanded", "\n$item_onehanded"); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDBAwakePatch { private static void Postfix(ObjectDB __instance) { Register(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class ObjectDBCopyPatch { private static void Postfix(ObjectDB __instance) { Register(__instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetSceneAwakePatch { private static void Postfix(ZNetScene __instance) { RegisterWithZNetScene(__instance); } } [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { private static void Postfix() { if ((Object)(object)ObjectDB.instance != (Object)null) { Register(ObjectDB.instance); } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDropAwakePatch { private static void Postfix(ItemDrop __instance) { if ((Object)(object)ObjectDB.instance == (Object)null) { return; } string prefabName = Utils.GetPrefabName(((Object)((Component)__instance).gameObject).name); if (prefabName != "Beeswax" || IsTemplateInstance(((Component)__instance).gameObject)) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { __instance.m_itemData.m_shared = component.m_itemData.m_shared; __instance.m_itemData.m_dropPrefab = itemPrefab; if (!((Component)__instance).gameObject.activeSelf) { ((Component)__instance).gameObject.SetActive(true); } } } } [HarmonyPatch(typeof(VisEquipment), "SetRightBackItem")] private static class VisEquipmentSetRightBackItemPatch { private static void Prefix(ref int itemHash) { if (itemHash == PrefabHash) { itemHash = 0; } } } [HarmonyPatch(typeof(VisEquipment), "SetRightItem")] private static class VisEquipmentSetRightItemPatch { private static void Postfix(VisEquipment __instance, int itemHash) { if (itemHash == PrefabHash) { ConfigureEquippedHandVisual(__instance, "Beeswax"); } } } [HarmonyPatch(typeof(VisEquipment), "SetRightItemVisual")] private static class VisEquipmentSetRightItemVisualPatch { private static void Postfix(VisEquipment __instance, int itemHash) { if (itemHash == PrefabHash) { ConfigureEquippedHandVisual(__instance, "Beeswax"); } } } internal const string PrefabName = "Beeswax"; private static readonly int PrefabHash = StringExtensionMethods.GetStableHashCode("Beeswax"); private const float IconDarkenRed = 0.55f; private const float IconDarkenGreen = 0.42f; private const float IconDarkenBlue = 0.22f; private const string EmbeddedIconResource = "Beeswax.icon.png"; private static readonly MethodInfo UpdateRegistersMethod = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); private static readonly MethodInfo OnCreateNewMethod = AccessTools.Method(typeof(ItemDrop), "OnCreateNew", new Type[2] { typeof(ItemDrop), typeof(bool) }, (Type[])null) ?? AccessTools.Method(typeof(ItemDrop), "OnCreateNew", new Type[1] { typeof(ItemDrop) }, (Type[])null); private static GameObject _prefabParent; private static Sprite _iconSprite; private const float HandVisualScale = 0.14f; private static readonly Vector3 HandVisualNudge = Vector3.zero; private static readonly Vector3 HandVisualRotation = Vector3.zero; internal static GameObject Prefab { get; private set; } internal static ItemDrop ItemDrop { get; private set; } internal static void EnsureItemConfigured(ItemData item) { if (item != null && IsBeeswaxItem(item)) { if ((Object)(object)ObjectDB.instance != (Object)null) { Register(ObjectDB.instance); } if ((Object)(object)ItemDrop != (Object)null) { item.m_shared = ItemDrop.m_itemData.m_shared; } if ((Object)(object)Prefab != (Object)null && (Object)(object)item.m_dropPrefab == (Object)null) { item.m_dropPrefab = Prefab; } } } internal static void ConfigureSharedData(SharedData shared) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (shared != null) { shared.m_equipDuration = 0f; shared.m_equipEffect = null; shared.m_unequipEffect = null; shared.m_holdStartEffect = null; shared.m_blockPower = 0f; shared.m_blockPowerPerLevel = 0f; shared.m_timedBlockBonus = 0f; shared.m_attackForce = 0f; shared.m_backstabBonus = 0f; shared.m_movementModifier = 0f; shared.m_blockable = false; shared.m_skillType = (SkillType)1; } } internal static bool IsBeeswaxItem(ItemData item) { if (item == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name == "Beeswax"; } if (item.m_shared != null) { return item.m_shared.m_name == "$item_beeswax"; } return false; } internal static void Register(ObjectDB db) { try { RegisterInternal(db); } catch (Exception arg) { BeeswaxPlugin.Log.LogError((object)$"Beeswax registration failed: {arg}"); } } private static void RegisterInternal(ObjectDB db) { if (!((Object)(object)db == (Object)null) && !((Object)(object)db.GetItemPrefab("Honey") == (Object)null)) { GameObject itemPrefab = db.GetItemPrefab("Honey"); if ((Object)(object)Prefab == (Object)null) { Prefab = CreateTemplate(itemPrefab, db); ItemDrop = Prefab.GetComponent<ItemDrop>(); BeeswaxPlugin.Log.LogInfo((object)"Created Beeswax item template."); } EnsureNetworkView(itemPrefab); if ((Object)(object)db.GetItemPrefab("Beeswax") == (Object)null) { db.m_items.Add(Prefab); UpdateRegistersMethod.Invoke(db, null); BeeswaxPlugin.Log.LogInfo((object)"Registered Beeswax with ObjectDB."); } if ((Object)(object)ZNetScene.instance != (Object)null) { RegisterWithZNetScene(ZNetScene.instance); } } } internal static void RegisterWithZNetScene(ZNetScene scene) { if ((Object)(object)scene == (Object)null || (Object)(object)Prefab == (Object)null) { return; } int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)Prefab).name); if (!(AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(scene) is Dictionary<int, GameObject> dictionary)) { BeeswaxPlugin.Log.LogWarning((object)"Could not access ZNetScene prefab table."); return; } if (!dictionary.ContainsKey(stableHashCode)) { dictionary.Add(stableHashCode, Prefab); } if (!scene.m_prefabs.Contains(Prefab)) { scene.m_prefabs.Add(Prefab); } } internal static void Drop(int amount, Vector3 position, Quaternion rotation) { //IL_003e: 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) if (amount <= 0) { return; } if ((Object)(object)ObjectDB.instance != (Object)null) { Register(ObjectDB.instance); } if ((Object)(object)ItemDrop == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Beeswax drop skipped: item is not registered yet."); return; } ItemDrop val = Object.Instantiate<ItemDrop>(ItemDrop, position, rotation); if ((Object)(object)val == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Beeswax drop skipped: instantiate failed."); return; } ((Component)val).gameObject.SetActive(true); int num = amount; if ((Object)(object)Game.instance != (Object)null) { num = Game.instance.ScaleDrops(val.m_itemData, num); } if (num <= 0) { Object.Destroy((Object)(object)((Component)val).gameObject); } else { val.SetStack(Mathf.Min(num, BeeswaxConfig.GetMaxStack())); } } private static GameObject GetPrefabParent() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_prefabParent == (Object)null) { _prefabParent = new GameObject("Beeswax_ModPrefabs"); _prefabParent.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_prefabParent); } return _prefabParent; } private static bool IsTemplateInstance(GameObject gameObject) { if ((Object)(object)Prefab != (Object)null) { return (Object)(object)gameObject == (Object)(object)Prefab; } return false; } private static void EnsureNetworkView(GameObject honeyPrefab) { //IL_007a: 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) if (!((Object)(object)Prefab == (Object)null) && !((Object)(object)honeyPrefab == (Object)null) && ZDOMan.instance != null && !((Object)(object)Prefab.GetComponent<ZNetView>() != (Object)null)) { ZNetView component = honeyPrefab.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Honey template is missing ZNetView; Beeswax cannot sync."); return; } ZNetView.StartGhostInit(); ZNetView obj = Prefab.AddComponent<ZNetView>(); obj.m_persistent = component.m_persistent; obj.m_distant = component.m_distant; obj.m_type = component.m_type; obj.m_syncInitialScale = component.m_syncInitialScale; ZNetView.FinishGhostInit(); BeeswaxPlugin.Log.LogInfo((object)"Attached network view to Beeswax template."); } } private static GameObject CreateTemplate(GameObject honeyPrefab, ObjectDB db) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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) ZNetView.m_forceDisableInit = true; GameObject val = Object.Instantiate<GameObject>(honeyPrefab, GetPrefabParent().transform); ((Object)val).name = "Beeswax"; ZNetView.m_forceDisableInit = false; ItemDrop component = val.GetComponent<ItemDrop>(); SharedData val2 = CloneSharedData(component.m_itemData.m_shared); ItemData val3 = component.m_itemData.Clone(); val3.m_shared = val2; val3.m_dropPrefab = val; component.m_itemData = val3; val2.m_name = "$item_beeswax"; val2.m_description = "$item_beeswax_description"; val2.m_itemType = (ItemType)19; val2.m_animationState = (AnimationState)1; val2.m_maxStackSize = BeeswaxConfig.GetMaxStack(); val2.m_food = 0f; val2.m_foodStamina = 0f; val2.m_foodEitr = 0f; val2.m_foodBurnTime = 0f; val2.m_foodRegen = 0f; val2.m_consumeStatusEffect = null; val2.m_setStatusEffect = null; val2.m_equipStatusEffect = null; val2.m_useDurability = false; val2.m_useDurabilityDrain = 0f; val2.m_damages = default(DamageTypes); val2.m_damagesPerLevel = default(DamageTypes); val2.m_attackStatusEffect = null; val2.m_attackStatusEffectChance = 0f; val2.m_attack = null; val2.m_secondaryAttack = null; val2.m_icons = BuildIcons(val2.m_icons); ConfigureSharedData(val2); TintRenderers(val); SetupHandAttach(val, db); CallOnCreateNew(component); return val; } private static void CallOnCreateNew(ItemDrop itemDrop) { if (OnCreateNewMethod == null) { BeeswaxPlugin.Log.LogWarning((object)"ItemDrop.OnCreateNew was not found; skipping world-level init."); return; } object[] parameters = ((OnCreateNewMethod.GetParameters().Length < 2) ? new object[1] { itemDrop } : new object[2] { itemDrop, false }); OnCreateNewMethod.Invoke(null, parameters); } private static void SetupHandAttach(GameObject beeswaxPrefab, ObjectDB db) { //IL_0080: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00c1: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) Transform val = beeswaxPrefab.transform.Find("attach"); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } MeshRenderer val2 = FindPrimaryDropRenderer(beeswaxPrefab); if ((Object)(object)val2 == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Beeswax prefab has no mesh for hand attach."); return; } MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Beeswax prefab mesh filter is missing for hand attach."); return; } Transform transform = ((Component)val2).transform; Bounds bounds = component.sharedMesh.bounds; Vector3 val3 = Vector3.Scale(((Bounds)(ref bounds)).center, transform.localScale); Vector3 localPosition = transform.localPosition + transform.localRotation * val3; GameObject val4 = new GameObject("attach"); val4.transform.SetParent(beeswaxPrefab.transform, false); val4.transform.localPosition = localPosition; val4.transform.localRotation = transform.localRotation; val4.transform.localScale = Vector3.one; bounds = component.sharedMesh.bounds; Vector3 val5 = Vector3.Scale(((Bounds)(ref bounds)).center, Vector3.one * 0.14f); GameObject val6 = new GameObject("beeswax_visual"); val6.transform.SetParent(val4.transform, false); val6.transform.localPosition = HandVisualNudge - val5; val6.transform.localRotation = Quaternion.Euler(HandVisualRotation); val6.transform.localScale = Vector3.one * 0.14f; val6.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; ((Renderer)val6.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)val2).sharedMaterials; } internal static void ConfigureEquippedHandVisual(VisEquipment visEquipment, string itemName) { if ((Object)(object)visEquipment == (Object)null || itemName != "Beeswax") { return; } Transform val = FindEquippedItemRoot(visEquipment, itemName); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.Find("attach"); if ((Object)(object)val2 == (Object)null && Utils.GetPrefabName(((Object)val).name) == "attach") { val2 = val; } MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val3 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && ((Component)val3).transform.IsChildOf(val2)) { ((Renderer)val3).enabled = true; } else { ((Renderer)val3).enabled = false; } } } private static Transform FindEquippedItemRoot(VisEquipment visEquipment, string itemName) { Transform[] componentsInChildren = ((Component)visEquipment).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { string prefabName = Utils.GetPrefabName(((Object)((Component)val).gameObject).name); if (prefabName == itemName) { return val; } if (prefabName == "attach" && (Object)(object)val.Find("beeswax_visual") != (Object)null) { return val; } } return null; } private static MeshRenderer FindPrimaryDropRenderer(GameObject beeswaxPrefab) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0084: 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_008d: 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) MeshRenderer result = null; float num = 0f; MeshRenderer[] componentsInChildren = beeswaxPrefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)((Component)val).transform.parent != (Object)null && ((Object)((Component)val).transform.parent).name == "attach") { continue; } MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) { Bounds bounds = component.sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num2 = size.x * size.y * size.z; if (!(num2 <= num)) { num = num2; result = val; } } } return result; } private static SharedData CloneSharedData(SharedData source) { return MemberwiseClone<SharedData>(source); } private static T MemberwiseClone<T>(T source) where T : class { return (T)typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(source, null); } private static Sprite[] BuildIcons(Sprite[] honeyIcons) { Sprite iconSprite = GetIconSprite(honeyIcons); if ((Object)(object)iconSprite == (Object)null) { return honeyIcons; } if (honeyIcons == null || honeyIcons.Length == 0) { return (Sprite[])(object)new Sprite[1] { iconSprite }; } Sprite[] array = (Sprite[])(object)new Sprite[honeyIcons.Length]; for (int i = 0; i < array.Length; i++) { array[i] = iconSprite; } return array; } private static Sprite GetIconSprite(Sprite[] honeyIcons) { if ((Object)(object)_iconSprite != (Object)null) { return _iconSprite; } Sprite val = LoadEmbeddedIconSprite(honeyIcons); if ((Object)(object)val != (Object)null) { _iconSprite = val; return _iconSprite; } if (honeyIcons == null || honeyIcons.Length == 0 || (Object)(object)honeyIcons[0] == (Object)null) { return null; } _iconSprite = DarkenSprite(honeyIcons[0]); return _iconSprite; } private static Sprite LoadEmbeddedIconSprite(Sprite[] honeyIcons) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) using Stream stream = typeof(BeeswaxItem).Assembly.GetManifestResourceStream("Beeswax.icon.png"); if (stream == null) { BeeswaxPlugin.Log.LogWarning((object)"Embedded beeswax icon was not found in the mod DLL."); return null; } byte[] array = new byte[stream.Length]; if (stream.Read(array, 0, array.Length) != array.Length) { BeeswaxPlugin.Log.LogWarning((object)"Failed to read embedded beeswax icon."); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; if (!TryLoadPng(val, array)) { Object.Destroy((Object)(object)val); BeeswaxPlugin.Log.LogWarning((object)"Failed to decode embedded beeswax icon."); return null; } float num = ((honeyIcons != null && honeyIcons.Length != 0 && (Object)(object)honeyIcons[0] != (Object)null) ? honeyIcons[0].pixelsPerUnit : 100f); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2((float)((Texture)val).width * 0.5f, (float)((Texture)val).height * 0.5f), num); } private static bool TryLoadPng(Texture2D texture, byte[] pngBytes) { Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule"); if (type != null) { MethodInfo method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[2] { typeof(Texture2D), typeof(byte[]) }, null); if (method != null) { return (bool)method.Invoke(null, new object[2] { texture, pngBytes }); } } MethodInfo method2 = typeof(Texture2D).GetMethod("LoadImage", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(byte[]) }, null); if (method2 != null) { return (bool)method2.Invoke(texture, new object[1] { pngBytes }); } return false; } private static Sprite DarkenSprite(Sprite source) { //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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } Rect textureRect = source.textureRect; int num = (int)((Rect)(ref textureRect)).width; int num2 = (int)((Rect)(ref textureRect)).height; if (num <= 0 || num2 <= 0) { return null; } Texture2D texture = source.texture; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); Graphics.Blit((Texture)(object)texture, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; val.ReadPixels(new Rect(((Rect)(ref textureRect)).x, ((Rect)(ref textureRect)).y, (float)num, (float)num2), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); Color[] pixels = val.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; pixels[i] = new Color(val2.r * 0.55f, val2.g * 0.42f, val2.b * 0.22f, val2.a); } val.SetPixels(pixels); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), source.pivot, source.pixelsPerUnit); } private static void TintRenderers(GameObject prefab) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if (!((Object)(object)val2 == (Object)null) && val2.HasProperty("_Color")) { Color color = val2.color; val2.color = new Color(color.r * 0.55f, color.g * 0.42f, color.b * 0.22f, color.a); } } } } } [BepInPlugin("ModdedWolf.Beeswax", "Beeswax", "1.0.5")] public class BeeswaxPlugin : BaseUnityPlugin { public const string GUID = "ModdedWolf.Beeswax"; public const string NAME = "Beeswax"; public const string VERSION = "1.0.5"; internal static BeeswaxPlugin Instance; internal static ManualLogSource Log; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; BeeswaxConfig.Init(((BaseUnityPlugin)this).Config); LocalizationSetup.Apply(); new Harmony("ModdedWolf.Beeswax").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Beeswax v1.0.5 loaded."); } } internal static class LocalizationSetup { internal const string ItemName = "$item_beeswax"; internal const string ItemDescription = "$item_beeswax_description"; internal const string SealedLabel = "$beeswax_sealed"; internal const string AlreadyWaxedLabel = "$beeswax_already_waxed"; internal const string ApplyLabel = "$beeswax_apply"; internal const string ScrapeLabel = "$beeswax_scrape"; internal const string ScrapedLabel = "$beeswax_scraped"; private static readonly MethodInfo AddWordMethod = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); private static readonly Dictionary<string, Dictionary<string, string>> Translations = new Dictionary<string, Dictionary<string, string>> { ["English"] = new Dictionary<string, string> { ["item_beeswax"] = "Beeswax", ["item_beeswax_description"] = "A heavy lump of beeswax. Rub it on timber to seal out the weather.", ["beeswax_sealed"] = "Waxed", ["beeswax_already_waxed"] = "Already waxed", ["beeswax_apply"] = "Apply beeswax", ["beeswax_scrape"] = "Scrape Beeswax", ["beeswax_scraped"] = "Scraped Beeswax" }, ["German"] = new Dictionary<string, string> { ["item_beeswax"] = "Bienenwachs", ["item_beeswax_description"] = "Ein schwerer Klumpen Bienenwachs. Reibe ihn auf Holzbauteile, um sie gegen Witterung zu schützen.", ["beeswax_sealed"] = "Gewachst", ["beeswax_already_waxed"] = "Bereits gewachst", ["beeswax_apply"] = "Bienenwachs auftragen", ["beeswax_scrape"] = "Bienenwachs abkratzen", ["beeswax_scraped"] = "Bienenwachs abgekratzt" }, ["French"] = new Dictionary<string, string> { ["item_beeswax"] = "Cire d'abeille", ["item_beeswax_description"] = "Un lourd morceau de cire d'abeille. Frottez-le sur le bois pour le protéger des intempéries.", ["beeswax_sealed"] = "Ciré", ["beeswax_already_waxed"] = "Déjà ciré", ["beeswax_apply"] = "Appliquer la cire d'abeille", ["beeswax_scrape"] = "Gratter la cire d'abeille", ["beeswax_scraped"] = "Cire d'abeille grattée" }, ["Italian"] = new Dictionary<string, string> { ["item_beeswax"] = "Cera d'api", ["item_beeswax_description"] = "Un pesante blocco di cera d'api. Strofinala sul legno per proteggerlo dalle intemperie.", ["beeswax_sealed"] = "Cerato", ["beeswax_already_waxed"] = "Già cerato", ["beeswax_apply"] = "Applica cera d'api", ["beeswax_scrape"] = "Raschia cera d'api", ["beeswax_scraped"] = "Cera d'api raschiata" }, ["Spanish"] = new Dictionary<string, string> { ["item_beeswax"] = "Cera de abejas", ["item_beeswax_description"] = "Un pesado trozo de cera de abejas. Frotalo sobre la madera para protegerla de la intemperie.", ["beeswax_sealed"] = "Encerado", ["beeswax_already_waxed"] = "Ya encerado", ["beeswax_apply"] = "Aplicar cera de abejas", ["beeswax_scrape"] = "Raspar cera de abejas", ["beeswax_scraped"] = "Cera de abejas raspada" }, ["Russian"] = new Dictionary<string, string> { ["item_beeswax"] = "Пчелиный воск", ["item_beeswax_description"] = "Тяжёлый кусок пчелиного воска. Натрите им дерево, чтобы защитить его от непогоды.", ["beeswax_sealed"] = "Пропитано воском", ["beeswax_already_waxed"] = "Уже пропитано воском", ["beeswax_apply"] = "Нанести пчелиный воск", ["beeswax_scrape"] = "Соскоблить пчелиный воск", ["beeswax_scraped"] = "Пчелиный воск соскоблен" }, ["Polish"] = new Dictionary<string, string> { ["item_beeswax"] = "Wosk pszczeli", ["item_beeswax_description"] = "Ciężki brył wosku pszczelego. Natrzyj nim drewno, aby chronić je przed warunkami atmosferycznymi.", ["beeswax_sealed"] = "Pokryte woskiem", ["beeswax_already_waxed"] = "Już pokryte woskiem", ["beeswax_apply"] = "Nałóż wosk pszczeli", ["beeswax_scrape"] = "Zeskrob wosk pszczeli", ["beeswax_scraped"] = "Wosk pszczeli zeskrobany" }, ["Portuguese_Brazilian"] = new Dictionary<string, string> { ["item_beeswax"] = "Cera de abelha", ["item_beeswax_description"] = "Um pesado pedaço de cera de abelha. Esfregue na madeira para protegê-la das intempéries.", ["beeswax_sealed"] = "Encerado", ["beeswax_already_waxed"] = "Já encerado", ["beeswax_apply"] = "Aplicar cera de abelha", ["beeswax_scrape"] = "Raspar cera de abelha", ["beeswax_scraped"] = "Cera de abelha raspada" }, ["Turkish"] = new Dictionary<string, string> { ["item_beeswax"] = "Balmumu", ["item_beeswax_description"] = "Ağır bir balmumu parçası. Hava koşullarından korumak için ahşaba sürün.", ["beeswax_sealed"] = "Balmumlanmış", ["beeswax_already_waxed"] = "Zaten balmumlanmış", ["beeswax_apply"] = "Balmumu uygula", ["beeswax_scrape"] = "Balmumunu kazı", ["beeswax_scraped"] = "Balmumu kazındı" }, ["Chinese"] = new Dictionary<string, string> { ["item_beeswax"] = "蜂蜡", ["item_beeswax_description"] = "一块沉重的蜂蜡。涂抹在木材上可防潮防雨。", ["beeswax_sealed"] = "已上蜡", ["beeswax_already_waxed"] = "已经上过蜡", ["beeswax_apply"] = "涂抹蜂蜡", ["beeswax_scrape"] = "刮除蜂蜡", ["beeswax_scraped"] = "已刮除蜂蜡" }, ["Chinese_Trad"] = new Dictionary<string, string> { ["item_beeswax"] = "蜂蠟", ["item_beeswax_description"] = "一塊沉重的蜂蠟。塗抹在木材上可防潮防雨。", ["beeswax_sealed"] = "已上蠟", ["beeswax_already_waxed"] = "已經上過蠟", ["beeswax_apply"] = "塗抹蜂蠟", ["beeswax_scrape"] = "刮除蜂蠟", ["beeswax_scraped"] = "已刮除蜂蠟" }, ["Japanese"] = new Dictionary<string, string> { ["item_beeswax"] = "蜜蝋", ["item_beeswax_description"] = "重い蜜蝋の塊。木材に擦りつけて天候から守る。", ["beeswax_sealed"] = "蝋引き済み", ["beeswax_already_waxed"] = "すでに蝋引き済み", ["beeswax_apply"] = "蜜蝋を塗る", ["beeswax_scrape"] = "蜜蝋を削り取る", ["beeswax_scraped"] = "蜜蝋を削り取った" }, ["Korean"] = new Dictionary<string, string> { ["item_beeswax"] = "밀랍", ["item_beeswax_description"] = "무거운 밀랍 덩어리. 목재에 문질러 날씨로부터 보호하세요.", ["beeswax_sealed"] = "왁스 처리됨", ["beeswax_already_waxed"] = "이미 왁스 처리됨", ["beeswax_apply"] = "밀랍 바르기", ["beeswax_scrape"] = "밀랍 긁어내기", ["beeswax_scraped"] = "밀랍을 긁어냄" }, ["Ukrainian"] = new Dictionary<string, string> { ["item_beeswax"] = "Бджолиний віск", ["item_beeswax_description"] = "Важкий шматок бджолиного воску. Натріть ним дерево, щоб захистити його від негоди.", ["beeswax_sealed"] = "Пропитано воском", ["beeswax_already_waxed"] = "Уже пропитано воском", ["beeswax_apply"] = "Нанести бджолиний віск", ["beeswax_scrape"] = "Зіскребти бджолиний віск", ["beeswax_scraped"] = "Бджолиний віск зіскребно" } }; internal static void Apply() { //IL_0005: 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_003e: Expected O, but got Unknown new Harmony("ModdedWolf.Beeswax.Localization").Patch((MethodBase)AccessTools.Method(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(LocalizationSetup), "SetupLanguagePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (Localization.instance != null) { RegisterWords(Localization.instance, Localization.instance.GetSelectedLanguage()); } } private static void SetupLanguagePostfix(Localization __instance, string language) { RegisterWords(__instance, language); } private static void RegisterWords(Localization localization, string language) { if (localization == null || AddWordMethod == null) { return; } if (!Translations.TryGetValue(language, out var value)) { value = Translations["English"]; } foreach (KeyValuePair<string, string> item in value) { AddWord(localization, item.Key, item.Value); } } private static void AddWord(Localization localization, string key, string value) { AddWordMethod.Invoke(localization, new object[2] { key, value }); } } internal static class ScrapeKeyHints { [HarmonyPatch(typeof(KeyHints), "UpdateHints")] private static class UpdateHintsPatch { private static void Postfix(KeyHints __instance) { CleanupLegacyTips(__instance); EnsureTips(__instance); if (!((Object)(object)_tipKb == (Object)null) || !((Object)(object)_tipGp == (Object)null)) { bool num = ShouldShow(__instance); bool flag = ZInput.IsGamepadActive(); bool active = num && !flag && (Object)(object)_tipKb != (Object)null; bool active2 = num && flag && (Object)(object)_tipGp != (Object)null; SetTipActive(_tipKb, active); SetTipActive(_tipGp, active2); } } } private const string TipObjectNameKb = "BeeswaxScrapeHintKB"; private const string TipObjectNameGp = "BeeswaxScrapeHintGP"; private const string LegacyTipObjectName = "BeeswaxScrapeHint"; private static GameObject _tipKb; private static GameObject _tipGp; private static int _failedKbId; private static int _failedGpId; private static bool _loggedKbFailure; private static bool _loggedGpFailure; private static bool ShouldShow(KeyHints keyHints) { if ((Object)(object)keyHints == (Object)null || (Object)(object)keyHints.m_combatHints == (Object)null || !keyHints.m_combatHints.activeInHierarchy) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !Waterproofing.IsHoldingKnife((Humanoid)(object)localPlayer)) { return false; } GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return false; } return Waterproofing.IsSealed(hoverObject.GetComponentInParent<WearNTear>()); } private static void EnsureTips(KeyHints keyHints) { if ((Object)(object)keyHints == (Object)null) { return; } if (!IsAlive(_tipKb)) { _tipKb = null; } if (!IsAlive(_tipGp)) { _tipGp = null; } if ((Object)(object)_tipKb == (Object)null && (Object)(object)keyHints.m_primaryAttackKB != (Object)null) { int instanceID = ((Object)keyHints.m_primaryAttackKB).GetInstanceID(); if (instanceID != _failedKbId) { _tipKb = CreateComposedTip(keyHints.m_primaryAttackKB, "BeeswaxScrapeHintKB", gamepad: false); if ((Object)(object)_tipKb == (Object)null) { _failedKbId = instanceID; } else { _failedKbId = 0; } } } if (!((Object)(object)_tipGp == (Object)null) || !((Object)(object)keyHints.m_primaryAttackGP != (Object)null)) { return; } int instanceID2 = ((Object)keyHints.m_primaryAttackGP).GetInstanceID(); if (instanceID2 != _failedGpId) { _tipGp = CreateComposedTip(keyHints.m_primaryAttackGP, "BeeswaxScrapeHintGP", gamepad: true); if ((Object)(object)_tipGp == (Object)null) { _failedGpId = instanceID2; } else { _failedGpId = 0; } } } private static GameObject CreateComposedTip(GameObject attackTip, string name, bool gamepad) { if ((Object)(object)attackTip == (Object)null || (Object)(object)attackTip.transform.parent == (Object)null) { return null; } Transform parent = attackTip.transform.parent; Transform val = parent.Find(name); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)(object)_tipKb && (Object)(object)((Component)val).gameObject != (Object)(object)_tipGp) { Object.Destroy((Object)(object)((Component)val).gameObject); } GameObject val2 = FindSiblingTip(parent, "Block", name); if ((Object)(object)val2 == (Object)null) { val2 = FindBlockTipByLabel(parent, name); } GameObject val3 = FindKeyBox(val2); GameObject val4 = FindKeyBox(attackTip); if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { LogLookupFailureOnce(gamepad, (Object)(object)val2 != (Object)null, (Object)(object)val3 != (Object)null, (Object)(object)val4 != (Object)null); return null; } GameObject val5 = Object.Instantiate<GameObject>(attackTip, parent, false); ((Object)val5).name = name; val5.transform.SetAsLastSibling(); TextMeshProUGUI val6 = FindTitleLabel(val5); if ((Object)(object)val6 != (Object)null && Localization.instance != null) { Localization.instance.RemoveTextFromCache((TMP_Text)(object)val6); ((TMP_Text)val6).text = Localization.instance.Localize("$beeswax_scrape"); } GameObject val7 = FindKeyBox(val5); if ((Object)(object)val7 == (Object)null) { Object.Destroy((Object)(object)val5); LogLookupFailureOnce(gamepad, (Object)(object)val2 != (Object)null, (Object)(object)val3 != (Object)null, attackBox: false); return null; } int siblingIndex = val7.transform.GetSiblingIndex(); GameObject obj = Object.Instantiate<GameObject>(val3, val5.transform, false); ((Object)obj).name = "BlockKey"; obj.SetActive(true); obj.transform.SetSiblingIndex(siblingIndex); GameObject val8 = CreatePlusLabel(val6, val5.transform); if ((Object)(object)val8 != (Object)null) { val8.transform.SetSiblingIndex(siblingIndex + 1); } val5.SetActive(false); return val5; } private static void LogLookupFailureOnce(bool gamepad, bool blockTip, bool blockBox, bool attackBox) { if (gamepad) { if (_loggedGpFailure) { return; } _loggedGpFailure = true; } else { if (_loggedKbFailure) { return; } _loggedKbFailure = true; } BeeswaxPlugin.Log.LogWarning((object)$"Could not find Block/Attack key boxes for scrape tip (blockTip={blockTip}, block={blockBox}, attack={attackBox}, gamepad={gamepad})."); } private static GameObject CreatePlusLabel(TextMeshProUGUI styleSource, Transform parent) { if ((Object)(object)styleSource == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(((Component)styleSource).gameObject, parent, false); ((Object)val).name = "Plus"; TextMeshProUGUI componentInChildren = val.GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren == (Object)null) { Object.Destroy((Object)(object)val); return null; } if (Localization.instance != null) { Localization.instance.RemoveTextFromCache((TMP_Text)(object)componentInChildren); } ((TMP_Text)componentInChildren).text = "+"; return val; } private static GameObject FindSiblingTip(Transform parent, string nameContains, string excludeName) { if ((Object)(object)parent == (Object)null) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (!((Object)(object)child == (Object)null) && !(((Object)child).name == excludeName) && ((Object)child).name.IndexOf(nameContains, StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)child).name.IndexOf("Beeswax", StringComparison.OrdinalIgnoreCase) < 0) { return ((Component)child).gameObject; } } return null; } private static GameObject FindBlockTipByLabel(Transform parent, string excludeName) { if ((Object)(object)parent == (Object)null || Localization.instance == null) { return null; } string text = Localization.instance.Localize("$settings_block"); if (string.IsNullOrEmpty(text) || text.StartsWith("$")) { text = "Block"; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child == (Object)null || ((Object)child).name == excludeName || ((Object)child).name.IndexOf("Attack", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)child).name.IndexOf("Dodge", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)child).name.IndexOf("Bow", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)child).name.IndexOf("Beeswax", StringComparison.OrdinalIgnoreCase) >= 0) { continue; } TextMeshProUGUI[] componentsInChildren = ((Component)child).GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val in componentsInChildren) { if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((TMP_Text)val).text) && ((TMP_Text)val).text.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { return ((Component)child).gameObject; } } } return null; } private static TextMeshProUGUI FindTitleLabel(GameObject tipRow) { if ((Object)(object)tipRow == (Object)null) { return null; } TextMeshProUGUI component = tipRow.GetComponent<TextMeshProUGUI>(); if ((Object)(object)component != (Object)null) { return component; } TextMeshProUGUI[] componentsInChildren = tipRow.GetComponentsInChildren<TextMeshProUGUI>(true); if (componentsInChildren.Length == 0) { return null; } return componentsInChildren[0]; } private static GameObject FindKeyBox(GameObject tipRow) { if ((Object)(object)tipRow == (Object)null) { return null; } TextMeshProUGUI val = FindTitleLabel(tipRow); Transform directChildBranch = GetDirectChildBranch(tipRow.transform, ((Object)(object)val != (Object)null) ? ((TMP_Text)val).transform : null); for (int i = 0; i < tipRow.transform.childCount; i++) { Transform child = tipRow.transform.GetChild(i); if (!((Object)(object)directChildBranch != (Object)null) || !((Object)(object)child == (Object)(object)directChildBranch)) { return ((Component)child).gameObject; } } if ((Object)(object)directChildBranch != (Object)null) { for (int j = 0; j < directChildBranch.childCount; j++) { Transform child2 = directChildBranch.GetChild(j); if (!((Object)(object)val != (Object)null) || (!((Object)(object)child2 == (Object)(object)((TMP_Text)val).transform) && !((TMP_Text)val).transform.IsChildOf(child2))) { return ((Component)child2).gameObject; } } } Transform[] componentsInChildren = tipRow.GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)(object)tipRow.transform || (Object)(object)val2 == (Object)(object)directChildBranch || ((Object)(object)val != (Object)null && ((Object)(object)val2 == (Object)(object)((TMP_Text)val).transform || val2.IsChildOf(((TMP_Text)val).transform)))) { continue; } string name = ((Object)val2).name; if (name.IndexOf("key", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("input", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("glyph", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("bind", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("button", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0) { Transform directChildBranch2 = GetDirectChildBranch(tipRow.transform, val2); if ((Object)(object)directChildBranch2 != (Object)null) { return ((Component)directChildBranch2).gameObject; } } } return null; } private static Transform GetDirectChildBranch(Transform root, Transform descendant) { if ((Object)(object)root == (Object)null || (Object)(object)descendant == (Object)null) { return null; } Transform val = descendant; while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)root) { val = val.parent; } if (!((Object)(object)val.parent == (Object)(object)root)) { return null; } return val; } private static void SetTipActive(GameObject tip, bool active) { if ((Object)(object)tip != (Object)null && tip.activeSelf != active) { tip.SetActive(active); } } private static void CleanupLegacyTips(KeyHints keyHints) { if (!((Object)(object)keyHints == (Object)null)) { if ((Object)(object)keyHints.m_dodgeKey != (Object)null) { DestroyNamedChild(((TMP_Text)keyHints.m_dodgeKey).transform.parent, "BeeswaxScrapeHint"); } if ((Object)(object)keyHints.m_primaryAttackKB != (Object)null) { DestroyNamedChild(keyHints.m_primaryAttackKB.transform.parent, "BeeswaxScrapeHint"); } if ((Object)(object)keyHints.m_primaryAttackGP != (Object)null) { DestroyNamedChild(keyHints.m_primaryAttackGP.transform.parent, "BeeswaxScrapeHint"); } } } private static void DestroyNamedChild(Transform parent, string name) { if (!((Object)(object)parent == (Object)null)) { Transform val = parent.Find(name); if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)(object)_tipKb) && !((Object)(object)((Component)val).gameObject == (Object)(object)_tipGp)) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } private static bool IsAlive(GameObject obj) { return (Object)(object)obj != (Object)null; } } internal static class StructureVisuals { private struct MaterialSnapshot { public Material Material; public bool HasColor; public Color Color; public bool HasGlossiness; public float Glossiness; public bool HasSmoothness; public float Smoothness; public bool HasEmission; public Color EmissionColor; public bool EmissionEnabled; } [HarmonyPatch(typeof(WearNTear), "Start")] private static class StartPatch { private static void Postfix(WearNTear __instance) { Waterproofing.ClearDisallowedSeal(__instance); EnsureApplied(__instance); } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] private static class UpdateWearPatch { private static void Postfix(WearNTear __instance) { Waterproofing.ClearDisallowedSeal(__instance); EnsureApplied(__instance); } } private const float WarmRed = 1.14f; private const float WarmGreen = 1.05f; private const float WarmBlue = 0.72f; private const float GlossBoost = 0.18f; private const string PieceShaderName = "Custom/Piece"; private const string RaftPrefabName = "Raft"; private const string RaftMastMaterialName = "Firetree_log"; private static readonly Color KarveWaxedColor = new Color(0.93f, 0.857f, 0.588f); private static readonly HashSet<int> AppliedIds = new HashSet<int>(); private static readonly Dictionary<int, List<MaterialSnapshot>> Snapshots = new Dictionary<int, List<MaterialSnapshot>>(); internal static void Apply(WearNTear wear) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) if (!BeeswaxConfig.ShowWaxedVisuals.Value || (Object)(object)wear == (Object)null || IsApplied(wear)) { return; } int instanceID = ((Object)wear).GetInstanceID(); bool flag = IsRaft(wear); List<MaterialSnapshot> list = new List<MaterialSnapshot>(); Renderer[] componentsInChildren = ((Component)wear).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Name == "ParticleSystemRenderer" || val is TrailRenderer || val is LineRenderer || !HasWaxableMaterial(val, flag)) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if (IsWaxableMaterial(val2, flag)) { MaterialSnapshot item = CaptureSnapshot(val2); list.Add(item); if (item.HasColor && flag) { val2.color = new Color(KarveWaxedColor.r, KarveWaxedColor.g, KarveWaxedColor.b, item.Color.a); } else if (item.HasColor) { Color color = item.Color; val2.color = new Color(Mathf.Min(color.r * 1.14f, 1f), Mathf.Min(color.g * 1.05f, 1f), Mathf.Min(color.b * 0.72f, 1f), color.a); } if (item.HasGlossiness) { val2.SetFloat("_Glossiness", Mathf.Min(item.Glossiness + 0.18f, 1f)); } else if (item.HasSmoothness) { val2.SetFloat("_Smoothness", Mathf.Min(item.Smoothness + 0.18f, 1f)); } } } } Snapshots[instanceID] = list; AppliedIds.Add(instanceID); } internal static void Revert(WearNTear wear) { //IL_0061: 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)wear == (Object)null) { return; } int instanceID = ((Object)wear).GetInstanceID(); if (!Snapshots.TryGetValue(instanceID, out var value)) { AppliedIds.Remove(instanceID); return; } foreach (MaterialSnapshot item in value) { Material material = item.Material; if ((Object)(object)material == (Object)null) { continue; } if (item.HasColor) { material.color = item.Color; } if (item.HasGlossiness) { material.SetFloat("_Glossiness", item.Glossiness); } if (item.HasSmoothness) { material.SetFloat("_Smoothness", item.Smoothness); } if (item.HasEmission) { material.SetColor("_EmissionColor", item.EmissionColor); if (item.EmissionEnabled) { material.EnableKeyword("_EMISSION"); } else { material.DisableKeyword("_EMISSION"); } } } Snapshots.Remove(instanceID); AppliedIds.Remove(instanceID); } internal static void RefreshAll() { WearNTear[] array = Object.FindObjectsByType<WearNTear>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { EnsureApplied(array[i]); } } internal static void EnsureApplied(WearNTear wear) { if ((Object)(object)wear == (Object)null) { return; } if (!BeeswaxConfig.ShowWaxedVisuals.Value) { if (IsApplied(wear)) { Revert(wear); } } else if (Waterproofing.IsSealed(wear)) { Apply(wear); } else if (IsApplied(wear) && HasValidZdo(wear)) { Revert(wear); } } private static bool HasValidZdo(WearNTear wear) { ZNetView component = ((Component)wear).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null) { return component.IsValid(); } return false; } private static MaterialSnapshot CaptureSnapshot(Material material) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_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) MaterialSnapshot result = new MaterialSnapshot { Material = material }; if (material.HasProperty("_Color")) { result.HasColor = true; result.Color = material.color; } if (material.HasProperty("_Glossiness")) { result.HasGlossiness = true; result.Glossiness = material.GetFloat("_Glossiness"); } else if (material.HasProperty("_Smoothness")) { result.HasSmoothness = true; result.Smoothness = material.GetFloat("_Smoothness"); } if (material.HasProperty("_EmissionColor")) { result.HasEmission = true; result.EmissionColor = material.GetColor("_EmissionColor"); result.EmissionEnabled = material.IsKeywordEnabled("_EMISSION"); } return result; } private static bool HasWaxableMaterial(Renderer renderer, bool isRaft) { Material[] sharedMaterials = renderer.sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { if (IsWaxableMaterial(sharedMaterials[i], isRaft)) { return true; } } return false; } private static bool IsWaxableMaterial(Material material, bool isRaft) { if ((Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null) { return false; } string name = ((Object)material).name; if (name.StartsWith("sail", StringComparison.OrdinalIgnoreCase)) { return false; } if (((Object)material.shader).name == "Custom/Piece") { return true; } if (isRaft) { return name.StartsWith("Firetree_log", StringComparison.OrdinalIgnoreCase); } return false; } private static bool IsRaft(WearNTear wear) { return Utils.GetPrefabName(((Object)((Component)wear).gameObject).name) == "Raft"; } private static bool IsApplied(WearNTear wear) { return AppliedIds.Contains(((Object)wear).GetInstanceID()); } } internal static class Waterproofing { [HarmonyPatch(typeof(Humanoid), "UseItem")] private static class UseItemPatch { private static void Prefix(ItemData item) { BeeswaxItem.EnsureItemConfigured(item); } } [HarmonyPatch(typeof(Player), "UseHotbarItem")] private static class UseHotbarItemPatch { private static void Prefix(Player __instance, int index) { BeeswaxItem.EnsureItemConfigured(((Humanoid)__instance).GetInventory().GetItemAt(index - 1, 0)); } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class PlayerSpawnedPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { RepairInventoryBeeswax(__instance); } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] private static class StartAttackPatch { private static bool Prefix(Humanoid __instance, Character target, bool secondaryAttack) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (IsHoldingBeeswax(__instance)) { if (!secondaryAttack) { ItemData rightItem = __instance.GetRightItem(); TryApplyOnce(__instance, __instance.GetInventory(), rightItem); } return false; } if (!secondaryAttack && IsHoldingKnife(__instance) && ((Character)__instance).IsBlocking() && TryUnsealOnce(__instance, __instance.GetInventory())) { _suppressStructureDamageUntil = Time.time + 0.75f; } return true; } } [HarmonyPatch(typeof(WearNTear), "Damage")] private static class WearNTearDamagePatch { private static bool Prefix(HitData hit) { if (Time.time > _suppressStructureDamageUntil) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !IsHoldingKnife((Humanoid)(object)localPlayer)) { return true; } Character val = ((hit != null) ? hit.GetAttacker() : null); if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)localPlayer) { return true; } return false; } } [HarmonyPatch(typeof(Player), "Update")] private static class PlayerUpdatePatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { RecoverLocalPlayerState(__instance); CleanupDepletedBeeswax(__instance); } } } [HarmonyPatch(typeof(WearNTear), "IsWet")] private static class IsWetPatch { private static void Postfix(WearNTear __instance, ref bool __result) { if (__result && IsSealed(__instance)) { __result = false; } } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] private static class HudCrosshairPatch { private static readonly FieldInfo HoverNameField = AccessTools.Field(typeof(Hud), "m_hoverName"); private static readonly PropertyInfo HoverTextProperty = HoverNameField?.FieldType.GetProperty("text", BindingFlags.Instance | BindingFlags.Public); private static readonly FieldInfo CrosshairField = AccessTools.Field(typeof(Hud), "m_crosshair"); private static readonly PropertyInfo CrosshairColorProperty = CrosshairField?.FieldType.GetProperty("color", BindingFlags.Instance | BindingFlags.Public); private static void Postfix(Hud __instance, Player player) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)(object)Player.m_localPlayer || HoverNameField == null || HoverTextProperty == null) { return; } GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return; } string text = BuildStructureHoverLine(hoverObject.GetComponentInParent<WearNTear>(), (Humanoid)(object)player); if (string.IsNullOrEmpty(text)) { return; } object value = HoverNameField.GetValue(__instance); if (value == null) { return; } string text2 = (HoverTextProperty.GetValue(value) as string) ?? string.Empty; string value2 = Localization.instance.Localize("$beeswax_sealed"); string value3 = Localization.instance.Localize("$beeswax_already_waxed"); if (!text2.Contains(value2) && !text2.Contains(value3)) { string text3 = (string.IsNullOrEmpty(text2) ? text : (text2 + "\n" + text)); HoverTextProperty.SetValue(value, text3); if (text3.Length > 0 && CrosshairField != null && CrosshairColorProperty != null) { object value4 = CrosshairField.GetValue(__instance); CrosshairColorProperty.SetValue(value4, Color.yellow); } } } } internal const string SealedKey = "beeswax_sealed"; private static readonly MethodInfo CharacterMessageMethod = FindLongestNamedMethod(typeof(Character), "Message"); private static readonly MethodInfo HudShowMessageMethod = FindLongestNamedMethod(typeof(MessageHud), "ShowMessage"); private static int _lastApplyFrame = -1; private static bool _recoveredLocalPlayerState; private static float _suppressStructureDamageUntil; internal static string BuildStructureHoverLine(WearNTear wear, Humanoid player) { if ((Object)(object)wear == (Object)null || !BeeswaxConfig.IsHoverTextAllowed()) { return null; } bool flag = (Object)(object)player != (Object)null && IsHoldingBeeswax(player); if (IsSealed(wear)) { if (flag) { if (!BeeswaxConfig.ShowAlreadyWaxedLabel.Value) { return null; } return "[<color=orange>★</color>] " + Localization.instance.Localize("$beeswax_already_waxed"); } if (!BeeswaxConfig.ShowWaxedLabel.Value) { return null; } return "[<color=orange>★</color>] " + Localization.instance.Localize("$beeswax_sealed"); } if (!CanCoat(wear) || !flag || !BeeswaxConfig.ShowApplyLabel.Value) { return null; } return Localization.instance.Localize("[<color=yellow><b>$KEY_Attack</b></color>] $beeswax_apply"); } private static void RepairInventoryBeeswax(Player player) { foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems()) { BeeswaxItem.EnsureItemConfigured(allItem); } } private static void RecoverLocalPlayerState(Player player) { if (!_recoveredLocalPlayerState) { _recoveredLocalPlayerState = true; RepairInventoryBeeswax(player); ItemData rightItem = ((Humanoid)player).GetRightItem(); if (BeeswaxItem.IsBeeswaxItem(rightItem)) { RefreshEquippedBeeswax(player, rightItem); } } } private static void RefreshEquippedBeeswax(Player player, ItemData item) { BeeswaxItem.EnsureItemConfigured(item); ((Humanoid)player).UnequipItem(item, false); BeeswaxItem.EnsureItemConfigured(item); ((Humanoid)player).EquipItem(item, false); } private static bool TryApplyOnce(Humanoid user, Inventory inventory, ItemData item) { if (Time.frameCount == _lastApplyFrame) { return false; } if (!TryApply(user, inventory, item)) { return false; } _lastApplyFrame = Time.frameCount; return true; } internal static bool TryApply(Humanoid user, Inventory inventory, ItemData item) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)user == (Object)null || inventory == null || item == null) { return false; } GameObject hoverObject = user.GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return false; } WearNTear componentInParent = hoverObject.GetComponentInParent<WearNTear>(); if (!CanCoat(componentInParent) || IsSealed(componentInParent)) { return false; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } if (!PrivateArea.CheckAccess(((Component)componentInParent).transform.position, 0f, true, false)) { ShowMessage((Character)(object)user, (MessageType)2, "$msg_privatearea"); return true; } inventory.RemoveItem(item, 1); component.GetZDO().Set("beeswax_sealed", 1); StructureVisuals.Apply(componentInParent); ApplySound.PlayAt(((Component)componentInParent).transform.position); ShowMessage((Character)(object)user, (MessageType)2, Localization.instance.Localize("$beeswax_sealed")); ((Character)user).m_zanim.SetTrigger("interact"); CleanupAfterApply(user, inventory, item); return true; } private static bool TryUnsealOnce(Humanoid user, Inventory inventory) { if (Time.frameCount == _lastApplyFrame) { return false; } if (!TryUnseal(user, inventory)) { return false; } _lastApplyFrame = Time.frameCount; return true; } private static bool TryUnseal(Humanoid user, Inventory inventory) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)user == (Object)null || inventory == null) { return false; } GameObject hoverObject = user.GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return false; } WearNTear componentInParent = hoverObject.GetComponentInParent<WearNTear>(); if (!IsSealed(componentInParent)) { return false; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } if (!PrivateArea.CheckAccess(((Component)componentInParent).transform.position, 0f, true, false)) { ShowMessage((Character)(object)user, (MessageType)2, "$msg_privatearea"); return true; } if (!RefundBeeswax(user, inventory)) { return false; } component.ClaimOwnership(); component.GetZDO().Set("beeswax_sealed", 0); StructureVisuals.Revert(componentInParent); ApplySound.PlayAt(((Component)componentInParent).transform.position); ShowMessage((Character)(object)user, (MessageType)2, Localization.instance.Localize("$beeswax_scraped")); return true; } private static bool RefundBeeswax(Humanoid user, Inventory inventory) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ObjectDB.instance != (Object)null) { BeeswaxItem.Register(ObjectDB.instance); } if ((Object)(object)BeeswaxItem.ItemDrop == (Object)null || (Object)(object)BeeswaxItem.Prefab == (Object)null) { BeeswaxPlugin.Log.LogWarning((object)"Beeswax refund failed: item is not registered yet."); return false; } ItemData val = BeeswaxItem.ItemDrop.m_itemData.Clone(); val.m_stack = 1; val.m_dropPrefab = BeeswaxItem.Prefab; val.m_worldLevel = (byte)Game.m_worldLevel; BeeswaxItem.EnsureItemConfigured(val); if (inventory.AddItem(val)) { return true; } Vector3 position = ((Component)user).transform.position + Vector3.up; BeeswaxItem.Drop(1, position, ((Component)user).transform.rotation); return true; } private static MethodInfo FindLongestNamedMethod(Type type, string name) { MethodInfo methodInfo = null; foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(type)) { if (!(declaredMethod.Name != name) && (methodInfo == null || declaredMethod.GetParameters().Length > methodInfo.GetParameters().Length)) { methodInfo = declaredMethod; } } return methodInfo; } private static object[] BuildMessageArgs(MethodInfo method, MessageType type, string msg) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) ParameterInfo[] parameters = method.GetParameters(); object[] array = new object[parameters.Length]; if (parameters.Length != 0) { array[0] = type; } if (parameters.Length > 1) { array[1] = msg; } for (int i = 2; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType == typeof(int)) { array[i] = 0; } else if (parameterType == typeof(bool)) { array[i] = false; } else { array[i] = null; } } return array; } private static void ShowMessage(Character user, MessageType type, string msg) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(msg)) { return; } try { if (CharacterMessageMethod != null && (Object)(object)user != (Object)null) { CharacterMessageMethod.Invoke(user, BuildMessageArgs(CharacterMessageMethod, type, msg)); } else if (HudShowMessageMethod != null && (Object)(object)MessageHud.instance != (Object)null) { HudShowMessageMethod.Invoke(MessageHud.instance, BuildMessageArgs(HudShowMessageMethod, type, msg)); } } catch (Exception ex) { BeeswaxPlugin.Log.LogWarning((object)("Could not show message: " + ex.Message)); } } private static void CleanupAfterApply(Humanoid user, Inventory inventory, ItemData item) { if (item.m_stack <= 0 || !inventory.ContainsItem(item)) { user.UnequipItem(item, true); } } private static void CleanupDepletedBeeswax(Player player) { ItemData rightItem = ((Humanoid)player).GetRightItem(); if (BeeswaxItem.IsBeeswaxItem(rightItem) && (rightItem.m_stack <= 0 || !((Humanoid)player).GetInventory().ContainsItem(rightItem))) { ((Humanoid)player).UnequipItem(rightItem, true); } } internal static bool IsSealed(WearNTear wear) { if ((Object)(object)wear == (Object)null || IsCraftingStationOrExtension(wear)) { return false; } ZNetView component = ((Component)wear).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { return component.GetZDO().GetInt("beeswax_sealed", 0) == 1; } return false; } internal static void ClearDisallowedSeal(WearNTear wear) { if ((Object)(object)wear == (Object)null || !IsCraftingStationOrExtension(wear)) { return; } ZNetView component = ((Component)wear).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO.GetInt("beeswax_sealed", 0) == 1) { StructureVisuals.Revert(wear); if (component.IsOwner()) { zDO.Set("beeswax_sealed", 0); } } } private static bool IsCraftingStationOrExtension(WearNTear wear) { if (!((Object)(object)((Component)wear).GetComponentInParent<CraftingStation>() != (Object)null)) { return (Object)(object)((Component)wear).GetComponentInParent<StationExtension>() != (Object)null; } return true; } private static bool CanCoat(WearNTear wear) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Invalid comparison between Unknown and I4 if ((Object)(object)wear == (Object)null) { return false; } if (IsCraftingStationOrExtension(wear)) { return false; } if ((Object)(object)((Component)wear).GetComponent<Beehive>() != (Object)null || (Object)(object)((Component)wear).GetComponentInParent<Beehive>() != (Object)null) { return false; } string prefabName = Utils.GetPrefabName(((Object)((Component)wear).gameObject).name); if (prefabName.IndexOf("bird", StringComparison.OrdinalIgnoreCase) >= 0 || prefabName.IndexOf("feather", StringComparison.OrdinalIgnoreCase) >= 0 || prefabName.Equals("Beehive", StringComparison.OrdinalIgnoreCase)) { return false; } switch (((object)Unsafe.As<MaterialType, MaterialType>(ref wear.m_materialType)/*cast due to .constrained prefix*/).ToString()) { case "Wood": case "HardWood": case "Timberwood": return true; default: { if ((int)wear.m_materialType != 2) { return false; } Piece piece = wear.m_piece; if ((Object)(object)piece == (Object)null) { return false; } string prefabName2 = Utils.GetPrefabName(((Object)((Component)piece).gameObject).name); if (!prefabName2.StartsWith("woodiron", StringComparison.OrdinalIgnoreCase) && !prefabName2.StartsWith("wood_iron", StringComparison.OrdinalIgnoreCase)) { return prefabName2.StartsWith("ironwood", StringComparison.OrdinalIgnoreCase); } return true; } } } private static bool IsHoldingBeeswax(Humanoid humanoid) { ItemData rightItem = humanoid.GetRightItem(); if (!BeeswaxItem.IsBeeswaxItem(rightItem)) { return false; } BeeswaxItem.EnsureItemConfigured(rightItem); if (rightItem.m_stack > 0) { return humanoid.GetInventory().ContainsItem(rightItem); } return false; } internal static bool IsHoldingKnife(Humanoid humanoid) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 ItemData rightItem = humanoid.GetRightItem(); if (rightItem?.m_shared != null) { return (int)rightItem.m_shared.m_skillType == 2; } return false; } } internal static class WildBeehivePatches { [HarmonyPatch(typeof(DropOnDestroyed), "OnDestroyed")] private static class OnDestroyedPatch { private static void Postfix(DropOnDestroyed __instance) { //IL_0047: 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_0052: 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) //IL_0070: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) try { if (!((Object)(object)__instance == (Object)null) && !(Utils.GetPrefabName(((Object)((Component)__instance).gameObject).name) != "Beehive") && !((Object)(object)ZoneSystem.instance == (Object)null)) { Vector3 position = ((Component)__instance).transform.position; float groundHeight = ZoneSystem.instance.GetGroundHeight(position); if (position.y < groundHeight) { position.y = groundHeight + 0.1f; } position += Vector3.up * (__instance.m_spawnYOffset + __instance.m_spawnYStep); BeeswaxItem.Drop(BeeswaxConfig.WildNestDropCount.Value, position, Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f)); } } catch (Exception arg) { BeeswaxPlugin.Log.LogError((object)$"Beeswax wild nest drop failed: {arg}"); } } } private const string WildBeehivePrefabName = "Beehive"; } internal static class WorldRepair { [HarmonyPatch(typeof(Game), "Start")] private static class GameStartPatch { private static void Postfix() { if (!((Object)(object)BeeswaxPlugin.Instance == (Object)null)) { ((MonoBehaviour)BeeswaxPlugin.Instance).StartCoroutine(RepairOnceDelayed()); } } } private const string RepairPrefKeyPrefix = "Beeswax.BeehiveRepair."; private const string WildBeehivePrefabName = "Beehive"; private const float RepairDelaySeconds = 5f; private static readonly int WildBeehiveHash = StringExtensionMethods.GetStableHashCode("Beehive"); private static readonly int BeeswaxHash = StringExtensionMethods.GetStableHashCode("Beeswax"); private static IEnumerator RepairOnceDelayed() { yield return (object)new WaitForSeconds(5f); while ((Object)(object)Player.m_localPlayer == (Object)null) { yield return null; } if (!ZNet.instance.IsServer()) { yield break; } World world = ZNet.World; if (world == null) { yield break; } string text = "Beeswax.BeehiveRepair." + world.m_uid; if (PlayerPrefs.GetInt(text, 0) != 1) { int num = FixStuckWildBeehives(); int num2 = CleanupRogueBeeswaxObjects(); PlayerPrefs.SetInt(text, 1); PlayerPrefs.Save(); if (num > 0 || num2 > 0) { BeeswaxPlugin.Log.LogInfo((object)$"One-time world repair applied: fixed {num} wild bee nest(s), removed {num2} rogue beeswax object(s)."); } else { BeeswaxPlugin.Log.LogInfo((object)"One-time world repair check completed (nothing needed fixing)."); } } } private static int FixStuckWildBeehives() { float num = GetWildBeehiveHealth(); if (num <= 0f) { num = 20f; } int num2 = 0; HashSet<ZDO> allZdos = GetAllZdos(); if (allZdos != null) { foreach (ZDO item in allZdos) { if (item != null && item.GetPrefab() == WildBeehiveHash && TryResetBeehiveHealth(item, num)) { num2++; } } } Destructible[] array = Object.FindObjectsByType<Destructible>((FindObjectsSortMode)0); foreach (Destructible val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponent<DropOnDestroyed>() == (Object)null) && !(Utils.GetPrefabName(((Object)((Component)val).gameObject).name) != "Beehive")) { ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && TryResetBeehiveHealth(component.GetZDO(), num)) { num2++; } } } return num2; } private static bool TryResetBeehiveHealth(ZDO zdo, float defaultHealth) { if (zdo == null) { return false; } float num = zdo.GetFloat(ZDOVars.s_health, defaultHealth); if (num > 0f && !float.IsNaN(num) && !float.IsInfinity(num)) { return false; } zdo.Set(ZDOVars.s_health, defaultHealth); return true; } private static float GetWildBeehiveHealth() { if ((Object)(object)ZNetScene.instance == (Object)null) { return 0f; } GameObject prefab = ZNetScene.instance.GetPrefab("Beehive"); Destructible val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Destructible>() : null); if ((Object)(object)val == (Object)null) { return 0f; } return val.m_health + (float)Game.m_worldLevel * val.m_health * Game.instance.m_worldLevelMineHPMultiplier; } private static int CleanupRogueBeeswaxObjects() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null || ZDOMan.instance == null) { return 0; } int num = 0; GameObject val = GameObject.Find("Beeswax_ModPrefabs"); ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsSortMode)0); foreach (ZNetView val2 in array) { if (!((Object)(object)val2 == (Object)null) && val2.IsValid() && !(Utils.GetPrefabName(((Object)((Component)val2).gameObject).name) != "Beeswax") && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val.transform)) && !((Object)(object)((Component)val2).GetComponent<ItemDrop>() == (Object)null)) { ZNetScene.instance.Destroy(((Component)val2).gameObject); num++; } } HashSet<ZDO> allZdos = GetAllZdos(); if (allZdos == null) { return num; } foreach (ZDO item in allZdos) { if (item != null && item.GetPrefab() == BeeswaxHash && !((Object)(object)ZNetScene.instance.FindInstance(item) != (Object)null)) { Vector3 position = item.GetPosition(); if (!(((Vector3)(ref position)).sqrMagnitude > 1f)) { ZDOMan.instance.DestroyZDO(item); num++; } } } return