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 Bear Taming v1.0.0
plugins/nick008-Bear_Taming.dll
Decompiled 15 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace Nick008TameableBear; [BepInProcess("valheim.exe")] [BepInPlugin("nick008.tameable_and_breadable_and_ridable_bear", "nick008-tameable_and_breadable_and_ridable_bear", "1.2.1")] public sealed class Nick008TameableBearPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetSceneAwakePatch { [HarmonyPrefix] private static void Prefix(ZNetScene __instance) { try { GameObject cub = RegisterCubBeforeSceneAwake(__instance); ConfigureBearCoreBeforeSceneAwake(__instance, cub); } catch (Exception ex) { if (Log != null) { Log.LogError((object)("[nick008-bear] Early bear setup failed: " + ex)); } } } } [HarmonyPatch(typeof(Tameable), "RPC_SetSaddle")] private static class BearSaddleRpcPatch { [HarmonyPostfix] private static void Postfix(Tameable __instance, object[] __args) { try { if (!IsBearTameable(__instance)) { return; } bool flag = false; if (__args != null) { for (int num = __args.Length - 1; num >= 0; num--) { if (__args[num] is bool) { flag = (bool)__args[num]; break; } } } Log.LogWarning((object)("[nick008-bear][DIAG] Bjorn RPC_SetSaddle fired, haveSaddle=" + flag)); SetBearSaddleVisual(__instance, flag); } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] RPC saddle visual sync failed: " + ex.Message)); } } } } [HarmonyPatch] private static class BearSadleAwakePatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("Sadle"); if (!(type != null)) { return null; } return AccessTools.Method(type, "Awake", (Type[])null, (Type[])null); } private static void Prefix(object __instance) { try { Component val = (Component)((__instance is Component) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.gameObject == (Object)null) && ((Object)val.gameObject).name.StartsWith("nick008_BearSaddle", StringComparison.Ordinal)) { PrepareBearSaddleRuntimeRefs(val, null); } } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] Sadle.Awake preparation failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Sadle), "ApplyControlls")] private static class BearSadleControlsPatch { [HarmonyPostfix] private static void Postfix(Sadle __instance, Vector3 moveDir, Vector3 lookDir, bool run, bool autoRun, bool block) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) try { if ((Object)(object)__instance == (Object)null) { return; } Character character = __instance.GetCharacter(); if ((Object)(object)character == (Object)null || (Object)(object)((Component)character).gameObject == (Object)null || character.GetLevel() < 3) { return; } Tameable component = ((Component)character).GetComponent<Tameable>(); if (!IsBearTameable(component)) { return; } Vector3 val = lookDir; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val)).Normalize(); } else { val = ((Component)character).transform.forward; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Vector3)(ref val)).Normalize(); } } float z = moveDir.z; if (Mathf.Abs(z) < 0.05f) { mountedBearDesiredDirection = Vector3.zero; } else { mountedBearDesiredDirection = val * Mathf.Sign(z); } mountedBearControlId = ((Object)character).GetInstanceID(); mountedBearWantsRun = run || autoRun; mountedBearControlTime = Time.time; character.SetMoveDir(mountedBearDesiredDirection); character.SetRun(mountedBearWantsRun); character.SetWalk(false); character.m_walkSpeed = Mathf.Max(character.m_walkSpeed, 1.5f); character.m_speed = Mathf.Max(character.m_speed, 3f); character.m_runSpeed = Mathf.Max(character.m_runSpeed, 7f); } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] 1.1.3 level3 control safeguard failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Player), "SetControls")] private static class BearMountedSuppressPlayerAttackPatch { [HarmonyPrefix] private static void Prefix(Player __instance, ref bool attack, ref bool secondaryAttack) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (Object)(object)GetControlledBearSaddle(__instance) != (Object)null) { attack = false; secondaryAttack = false; } } } [HarmonyPatch(typeof(Player), "Update")] private static class BearMountedAttackPatch { private static void TriggerBearAttack(Humanoid bear, int preferredIndex) { if ((Object)(object)bear == (Object)null || ((Character)bear).InAttack() || bear.m_defaultItems == null || bear.m_defaultItems.Length == 0) { return; } int num = preferredIndex; if (num < 0 || num >= bear.m_defaultItems.Length || (Object)(object)bear.m_defaultItems[num] == (Object)null) { num = 0; } if (num >= bear.m_defaultItems.Length || (Object)(object)bear.m_defaultItems[num] == (Object)null) { return; } ItemDrop component = bear.m_defaultItems[num].GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { FieldInfo fieldInfo = AccessTools.Field(typeof(Humanoid), "m_rightItem"); if (!(fieldInfo == null)) { fieldInfo.SetValue(bear, component.m_itemData); ((Character)bear).StartAttack((Character)null, false); } } } [HarmonyPostfix] private static void Postfix(Player __instance) { try { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } Sadle controlledBearSaddle = GetControlledBearSaddle(__instance); if ((Object)(object)controlledBearSaddle == (Object)null) { return; } Character character = controlledBearSaddle.GetCharacter(); Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if (!((Object)(object)val == (Object)null)) { if (ZInput.GetButtonDown("Attack")) { TriggerBearAttack(val, 0); } else if (ZInput.GetButtonDown("SecondaryAttack")) { TriggerBearAttack(val, 1); } } } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] 1.1.3 mounted attack failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(Tameable), "GetHoverText")] private static class BearRideHoverPatch { [HarmonyPostfix] private static void Postfix(Tameable __instance, ref string __result) { try { if (IsBearTameable(__instance) && BearHasSaddle(__instance) && !string.IsNullOrEmpty(__result) && __result.IndexOf("Nasednout", StringComparison.OrdinalIgnoreCase) < 0) { __result = "<color=yellow>[LeftAlt + E]</color> Nasednout\\n" + __result; } } catch { } } } [HarmonyPatch] private static class BearDirectRidePatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(Tameable).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo method in methods) { if (method.Name != "Interact" || method.ReturnType != typeof(bool)) { continue; } ParameterInfo[] parameters = method.GetParameters(); bool hasHumanoid = false; for (int j = 0; j < parameters.Length; j++) { if (typeof(Humanoid).IsAssignableFrom(parameters[j].ParameterType)) { hasHumanoid = true; break; } } if (hasHumanoid) { yield return method; } } } private static bool TryRide(Component saddle, Humanoid humanoid, out bool ridden) { ridden = false; if ((Object)(object)saddle == (Object)null || (Object)(object)humanoid == (Object)null) { return false; } PrepareBearSaddleRuntimeRefs(saddle, ((Object)(object)saddle.GetComponentInParent<Tameable>() != (Object)null) ? ((Component)saddle.GetComponentInParent<Tameable>()).gameObject : null); MethodInfo[] methods = ((object)saddle).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "Interact" || methodInfo.ReturnType != typeof(bool)) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; bool flag = true; bool flag2 = false; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; if (typeof(Humanoid).IsAssignableFrom(parameterType)) { array[j] = humanoid; flag2 = true; continue; } if (parameterType == typeof(bool)) { array[j] = false; continue; } flag = false; break; } if (flag && flag2) { object obj = methodInfo.Invoke(saddle, array); if (obj is bool) { ridden = (bool)obj; return true; } } } return false; } private static bool TryForceRide(Component saddle, Humanoid humanoid, out bool attached, out bool controllerStarted, out bool validUser) { //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) attached = false; controllerStarted = false; validUser = false; Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if ((Object)(object)saddle == (Object)null || (Object)(object)val == (Object)null) { return false; } Tameable componentInParent = saddle.GetComponentInParent<Tameable>(); GameObject val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : null); PrepareBearSaddleRuntimeRefs(saddle, val2); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = ((object)saddle).GetType().GetField("m_attachPoint", bindingAttr); FieldInfo field2 = ((object)saddle).GetType().GetField("m_attachAnimation", bindingAttr); FieldInfo field3 = ((object)saddle).GetType().GetField("m_detachOffset", bindingAttr); FieldInfo field4 = ((object)saddle).GetType().GetField("m_haveValidUser", bindingAttr); Transform val3 = (Transform)((field != null) ? /*isinst with value type is only supported in some contexts*/: null); string text = ((field2 != null) ? (field2.GetValue(saddle) as string) : null); Vector3 val4 = Vector3.zero; if (field3 != null) { object value = field3.GetValue(saddle); if (value is Vector3) { val4 = (Vector3)value; } } if ((Object)(object)val3 == (Object)null) { return false; } if (string.IsNullOrEmpty(text)) { text = "attach_lox"; } try { IDoodadController val5 = (IDoodadController)(object)((saddle is IDoodadController) ? saddle : null); if (val5 != null) { MethodInfo method = typeof(Player).GetMethod("StartDoodadControl", bindingAttr, null, new Type[1] { typeof(IDoodadController) }, null); if (method != null) { method.Invoke(val, new object[1] { val5 }); controllerStarted = true; } } } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] Force mount StartDoodadControl failed: " + ex.Message)); } } try { MethodInfo method2 = typeof(Character).GetMethod("AttachStart", bindingAttr, null, new Type[8] { typeof(Transform), typeof(GameObject), typeof(bool), typeof(bool), typeof(bool), typeof(string), typeof(Vector3), typeof(Transform) }, null); if (method2 != null) { method2.Invoke(val, new object[8] { val3, val2, false, false, false, text, val4, null }); } } catch (Exception ex2) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] Force mount AttachStart failed: " + ex2.Message)); } } try { MethodInfo method3 = typeof(Character).GetMethod("IsAttached", bindingAttr, null, Type.EmptyTypes, null); if (method3 != null) { object obj = method3.Invoke(val, null); if (obj is bool) { attached = (bool)obj; } } } catch { } try { if (field4 != null) { object value2 = field4.GetValue(saddle); if (value2 is bool) { validUser = (bool)value2; } if (controllerStarted && !validUser) { field4.SetValue(saddle, true); validUser = true; } } } catch { } if (!attached) { return controllerStarted; } return true; } private static bool Prefix(Tameable __instance, object[] __args, ref bool __result) { //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown try { if (!IsBearTameable(__instance) || !BearHasSaddle(__instance)) { return true; } if (!Input.GetKey((KeyCode)308) && !Input.GetKey((KeyCode)307)) { return true; } Humanoid val = null; bool flag = false; if (__args != null) { bool flag2 = false; for (int i = 0; i < __args.Length; i++) { if (__args[i] is Humanoid) { val = (Humanoid)__args[i]; } else if (__args[i] is bool && !flag2) { flag = (bool)__args[i]; flag2 = true; } } } if ((Object)(object)val == (Object)null || flag) { return true; } Component bearSaddleComponent = GetBearSaddleComponent(__instance); if ((Object)(object)bearSaddleComponent == (Object)null) { if (Log != null) { Log.LogWarning((object)"[nick008-bear] LeftAlt+E mount attempt: bear saddle component is null."); } return true; } bool ridden; bool flag3 = TryRide(bearSaddleComponent, val, out ridden); if (Log != null) { Log.LogInfo((object)("[nick008-bear] LeftAlt+E mount attempt. Saddle.Interact called=" + flag3 + ", result=" + ridden)); if (!ridden) { try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = ((object)bearSaddleComponent).GetType().GetField("m_character", bindingAttr); FieldInfo field2 = ((object)bearSaddleComponent).GetType().GetField("m_nview", bindingAttr); FieldInfo field3 = ((object)bearSaddleComponent).GetType().GetField("m_tambable", bindingAttr); FieldInfo field4 = ((object)bearSaddleComponent).GetType().GetField("m_monsterAI", bindingAttr); FieldInfo field5 = ((object)bearSaddleComponent).GetType().GetField("m_attachPoint", bindingAttr); Character val2 = (Character)((field != null) ? /*isinst with value type is only supported in some contexts*/: null); ZNetView val3 = (ZNetView)((field2 != null) ? /*isinst with value type is only supported in some contexts*/: null); Tameable val4 = (Tameable)((field3 != null) ? /*isinst with value type is only supported in some contexts*/: null); MonsterAI val5 = (MonsterAI)((field4 != null) ? /*isinst with value type is only supported in some contexts*/: null); Transform val6 = (Transform)((field5 != null) ? /*isinst with value type is only supported in some contexts*/: null); object obj = null; bool flag4 = false; bool flag5 = false; bool flag6 = false; bool flag7 = false; try { MethodInfo method = ((object)bearSaddleComponent).GetType().GetMethod("GetUser", bindingAttr, null, Type.EmptyTypes, null); if (method != null) { obj = method.Invoke(bearSaddleComponent, null); } } catch { } try { FieldInfo field6 = ((object)bearSaddleComponent).GetType().GetField("m_haveValidUser", bindingAttr); if (field6 != null) { object value = field6.GetValue(bearSaddleComponent); if (value is bool) { flag4 = (bool)value; } } } catch { } try { MethodInfo methodInfo = (((Object)(object)val4 != (Object)null) ? ((object)val4).GetType().GetMethod("HaveRider", bindingAttr, null, Type.EmptyTypes, null) : null); if (methodInfo != null) { object obj4 = methodInfo.Invoke(val4, null); if (obj4 is bool) { flag5 = (bool)obj4; } } } catch { } try { flag6 = (Object)(object)val3 != (Object)null && val3.IsOwner(); } catch { } try { flag7 = (Object)(object)val2 != (Object)null && val2.IsTamed(); } catch { } float num = (((Object)(object)val != (Object)null) ? Vector3.Distance(((Component)val).transform.position, bearSaddleComponent.transform.position) : (-1f)); Log.LogInfo((object)("[nick008-bear] Mount fail state: character=" + ((Object)(object)val2 != (Object)null) + ", tamed=" + flag7 + ", nview=" + ((Object)(object)val3 != (Object)null) + ", nviewValid=" + ((Object)(object)val3 != (Object)null && val3.IsValid()) + ", nviewOwner=" + flag6 + ", tameable=" + ((Object)(object)val4 != (Object)null) + ", haveRider=" + flag5 + ", monsterAI=" + ((Object)(object)val5 != (Object)null) + ", attachPoint=" + ((Object)(object)val6 != (Object)null) + ", haveValidUser=" + flag4 + ", getUser=" + ((obj != null) ? obj.ToString() : "<null>") + ", saddleActiveSelf=" + bearSaddleComponent.gameObject.activeSelf + ", saddleActiveHierarchy=" + bearSaddleComponent.gameObject.activeInHierarchy + ", userDistance=" + num.ToString("0.00") + ", colliders=" + bearSaddleComponent.GetComponents<Collider>().Length)); } catch (Exception ex) { Log.LogWarning((object)("[nick008-bear] Mount fail diagnostic failed: " + ex.Message)); } } } if (flag3 && ridden) { __result = true; return false; } if (Log != null) { Log.LogWarning((object)"[nick008-bear] Native Sadle.Interact still returned false. Check userDistance in Mount fail state."); } __result = false; return false; } catch (Exception ex2) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] LeftAlt+E ride patch failed: " + ex2)); } __result = false; return false; } } } public const string PluginGuid = "nick008.tameable_and_breadable_and_ridable_bear"; public const string PluginName = "nick008-tameable_and_breadable_and_ridable_bear"; public const string PluginVersion = "1.2.1"; private const float TamingTime = 1500f; private const float FedDuration = 300f; private const float GrowTime = 2000f; private const int MaxNearbyBears = 5; private const float PregnancyChance = 0.66f; private const float PregnancyDuration = 90f; private const float CubScale = 0.55f; private const string BearPrefabName = "Bjorn"; private const string LoxPrefabName = "Lox"; private const string CubPrefabName = "nick008_BearCub"; private const string SaddleObjectName = "nick008_BearSaddle"; private const string SaddleVisualName = "nick008_BearSaddleVisual"; private const string MountPointName = "nick008_BearMountPoint"; private const string BearSaddleItemPrefabName = "nick008_BearSaddleItem"; private const string BearSaddleItemDisplayName = "Bear Saddle"; private const string BearSaddleItemDescription = "A sturdy saddle made for riding a tamed bear."; private const string BearSaddleRecipeName = "Recipe_nick008_BearSaddle"; private const float Level3MountedScaleCap = 1.25f; internal static ManualLogSource Log; internal static Nick008TameableBearPlugin Instance; private static readonly string[] FoodPrefabNames = new string[4] { "Blueberries", "Honey", "RawMeat", "DeerMeat" }; private int configuredSceneId = int.MinValue; private GameObject offspringRoot; private static bool ridingDiagnosticsDumped = false; private static readonly Dictionary<int, GameObject> saddleVisualCache = new Dictionary<int, GameObject>(); private GameObject customSaddlePrefabRoot; private static int customSaddleConfiguredDbId = int.MinValue; private static int mountedBearControlId = -1; private static Vector3 mountedBearDesiredDirection = Vector3.zero; private static bool mountedBearWantsRun = false; private static float mountedBearControlTime = -999f; private static readonly HashSet<int> mountedBearDiagnosticsLogged = new HashSet<int>(); private static Character level3ScaledBear = null; private static Vector3 level3OriginalLocalScale = Vector3.one; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; new Harmony("nick008.tameable_and_breadable_and_ridable_bear").PatchAll(); Log.LogInfo((object)"[nick008-bear] 1.2.1 LIVE loaded. Fixed leftover test taming/growth values to normal gameplay values; Bear Saddle and riding features unchanged."); ((MonoBehaviour)this).StartCoroutine(WatchForCreatureDatabase()); } internal static GameObject RegisterCubBeforeSceneAwake(ZNetScene scene) { //IL_00de: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown if ((Object)(object)scene == (Object)null || (Object)(object)Instance == (Object)null) { return null; } GameObject val = FindPrefabInSceneList(scene, "nick008_BearCub"); if ((Object)(object)val != (Object)null) { return val; } GameObject val2 = FindPrefabInSceneList(scene, "Bjorn"); if ((Object)(object)val2 == (Object)null) { if (Log != null) { Log.LogError((object)"[nick008-bear] Vanilla prefab 'Bjorn' was not found."); } return null; } if ((Object)(object)Instance.offspringRoot == (Object)null) { Instance.offspringRoot = new GameObject("nick008tameablebear_offspring_root"); Instance.offspringRoot.transform.SetParent(((Component)Instance).transform, false); Instance.offspringRoot.SetActive(false); } GameObject val3 = Object.Instantiate<GameObject>(val2, Instance.offspringRoot.transform); ((Object)val3).name = "nick008_BearCub"; val3.transform.localScale = val3.transform.localScale * 0.55f; CharacterDrop component = val3.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } Tameable component2 = val3.GetComponent<Tameable>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } Procreation component3 = val3.GetComponent<Procreation>(); if ((Object)(object)component3 != (Object)null) { Object.DestroyImmediate((Object)(object)component3); } Growup val4 = val3.GetComponent<Growup>(); if ((Object)(object)val4 == (Object)null) { val4 = val3.AddComponent<Growup>(); } val4.m_grownPrefab = val2; val4.m_growTime = 2000f; scene.m_prefabs.Add(val3); if (Log != null) { Log.LogInfo((object)"[nick008-bear] Early-registered persistent bear cub prefab."); } return val3; } internal static bool ConfigureBearCoreBeforeSceneAwake(ZNetScene scene, GameObject cub) { if ((Object)(object)scene == (Object)null || (Object)(object)cub == (Object)null) { return false; } GameObject val = FindPrefabInSceneList(scene, "Bjorn"); GameObject val2 = FindPrefabInSceneList(scene, "Lox"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { if (Log != null) { Log.LogError((object)"[nick008-bear] Bjorn or Lox prefab was not found."); } return false; } MonsterAI component = val.GetComponent<MonsterAI>(); Tameable component2 = val2.GetComponent<Tameable>(); Procreation component3 = val2.GetComponent<Procreation>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null) { if (Log != null) { Log.LogError((object)"[nick008-bear] Required vanilla Bjorn/Lox components were not found."); } return false; } Tameable val3 = val.GetComponent<Tameable>(); if ((Object)(object)val3 == (Object)null) { val3 = val.AddComponent<Tameable>(); CopyPublicFields((Component)(object)val3, (Component)(object)component2); } val3.m_commandable = true; val3.m_startsTamed = false; val3.m_tamingTime = 1500f; val3.m_fedDuration = 300f; if (component.m_consumeItems == null) { component.m_consumeItems = new List<ItemDrop>(); } Procreation val4 = val.GetComponent<Procreation>(); if ((Object)(object)val4 == (Object)null) { val4 = val.AddComponent<Procreation>(); CopyPublicFields((Component)(object)val4, (Component)(object)component3); } val4.m_maxCreatures = 5; val4.m_pregnancyChance = 0.66f; val4.m_pregnancyDuration = 90f; val4.m_offspring = cub; SetupBearRiding(val, val2, val3, component2); if (Log != null) { Log.LogInfo((object)"[nick008-bear] Early-configured Bjorn taming, breeding and Lox riding system."); } return true; } private IEnumerator WatchForCreatureDatabase() { while (true) { try { ZNetScene instance = ZNetScene.instance; ObjectDB instance2 = ObjectDB.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance2 != (Object)null && (Object)(object)instance.GetPrefab("Bjorn") != (Object)null && (Object)(object)instance.GetPrefab("Lox") != (Object)null && (Object)(object)instance2.GetItemPrefab("Honey") != (Object)null) { int instanceID = ((Object)instance).GetInstanceID(); if (instanceID != configuredSceneId) { GameObject prefab = instance.GetPrefab("Bjorn"); GameObject prefab2 = instance.GetPrefab("nick008_BearCub"); if ((Object)(object)prefab != (Object)null && (Object)(object)prefab2 != (Object)null) { ConfigureFoodsOnPrefab(prefab, instance2); configuredSceneId = instanceID; Log.LogInfo((object)"[nick008-bear] Food setup completed."); } } if (configuredSceneId == instanceID) { UpdateLoadedBearFoods(instance2); GameObject val = EnsureDedicatedBearSaddle(instance2, instance); if ((Object)(object)val != (Object)null) { ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { ApplyDedicatedBearSaddleToBears(instance, component); } } if ((Object)(object)Player.m_localPlayer != (Object)null) { RefreshLoadedBearSaddles(instance2); } } } } catch (Exception ex) { Log.LogError((object)("[nick008-bear] Setup watcher error: " + ex)); } yield return (object)new WaitForSeconds(1f); } } private static bool IsBearTameable(Tameable tameable) { if ((Object)(object)tameable == (Object)null || (Object)(object)((Component)tameable).gameObject == (Object)null) { return false; } string text = ((Object)((Component)tameable).gameObject).name ?? string.Empty; return text.StartsWith("Bjorn", StringComparison.OrdinalIgnoreCase); } private static Component GetBearSaddleComponent(Tameable tameable) { if ((Object)(object)tameable == (Object)null) { return null; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeof(Tameable).GetField("m_saddle", bindingAttr); if (field == null) { return null; } object? value = field.GetValue(tameable); return (Component)((value is Component) ? value : null); } private static bool TryInvokeBoolNoArgs(object instance, string methodName, out bool value) { value = false; if (instance == null) { return false; } try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = instance.GetType().GetMethod(methodName, bindingAttr, null, Type.EmptyTypes, null); if (method == null || method.ReturnType != typeof(bool)) { return false; } object obj = method.Invoke(instance, null); if (obj is bool) { value = (bool)obj; return true; } } catch { } return false; } private static bool ReadHaveSaddleFromZdo(Tameable tameable, out bool haveSaddle) { haveSaddle = false; if ((Object)(object)tameable == (Object)null || (Object)(object)((Component)tameable).gameObject == (Object)null) { return false; } try { Component val = FindComponentByTypeName(((Component)tameable).gameObject, "ZNetView"); if ((Object)(object)val == (Object)null) { return false; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = ((object)val).GetType().GetMethod("GetZDO", bindingAttr, null, Type.EmptyTypes, null); if (method == null) { return false; } object obj = method.Invoke(val, null); if (obj == null) { return false; } MethodInfo method2 = obj.GetType().GetMethod("GetBool", bindingAttr, null, new Type[2] { typeof(string), typeof(bool) }, null); MethodInfo method3 = obj.GetType().GetMethod("GetBool", bindingAttr, null, new Type[1] { typeof(string) }, null); string[] array = new string[4] { "HaveSaddle", "haveSaddle", "Saddle", "saddle" }; for (int i = 0; i < array.Length; i++) { if (method2 != null) { object obj2 = method2.Invoke(obj, new object[2] { array[i], false }); if (obj2 is bool && (bool)obj2) { haveSaddle = true; return true; } } if (method3 != null) { object obj3 = method3.Invoke(obj, new object[1] { array[i] }); if (obj3 is bool && (bool)obj3) { haveSaddle = true; return true; } } } return true; } catch { } return false; } private static bool BearHasSaddle(Tameable tameable) { string[] array = new string[3] { "HaveSaddle", "HasSaddle", "IsSaddled" }; bool value; for (int i = 0; i < array.Length; i++) { if (TryInvokeBoolNoArgs(tameable, array[i], out value) && value) { return true; } } if (ReadHaveSaddleFromZdo(tameable, out value) && value) { return true; } return false; } private static void ForceActiveHierarchy(GameObject root) { if ((Object)(object)root == (Object)null) { return; } root.SetActive(true); Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Component)componentsInChildren[i]).gameObject.SetActive(true); } } Renderer[] componentsInChildren2 = root.GetComponentsInChildren<Renderer>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { componentsInChildren2[j].enabled = true; } } Collider[] componentsInChildren3 = root.GetComponentsInChildren<Collider>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { if ((Object)(object)componentsInChildren3[k] != (Object)null) { componentsInChildren3[k].enabled = true; } } } private static GameObject GetBearSaddleVisualObject(Tameable tameable) { if ((Object)(object)tameable == (Object)null || (Object)(object)((Component)tameable).gameObject == (Object)null) { return null; } int instanceID = ((Object)((Component)tameable).gameObject).GetInstanceID(); if (saddleVisualCache.TryGetValue(instanceID, out var value)) { if ((Object)(object)value != (Object)null) { return value; } saddleVisualCache.Remove(instanceID); } Transform val = FindVisualRoot(((Component)tameable).gameObject); if ((Object)(object)val == (Object)null) { return null; } Transform val2 = FindChildRecursive(val, "nick008_BearSaddleVisual"); if ((Object)(object)val2 != (Object)null) { saddleVisualCache[instanceID] = ((Component)val2).gameObject; return ((Component)val2).gameObject; } return null; } private static void SetBearSaddleVisual(Tameable tameable, bool haveSaddle) { Component bearSaddleComponent = GetBearSaddleComponent(tameable); GameObject bearSaddleVisualObject = GetBearSaddleVisualObject(tameable); if ((Object)(object)bearSaddleComponent != (Object)null && (Object)(object)bearSaddleComponent.gameObject != (Object)null) { try { PrepareBearSaddleRuntimeRefs(bearSaddleComponent, ((Object)(object)tameable != (Object)null) ? ((Component)tameable).gameObject : null); bearSaddleComponent.gameObject.SetActive(haveSaddle); } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] Could not toggle logical bear saddle: " + ex.Message)); } } } if (!((Object)(object)bearSaddleVisualObject != (Object)null)) { return; } bearSaddleVisualObject.SetActive(haveSaddle); Renderer[] componentsInChildren = bearSaddleVisualObject.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].enabled = haveSaddle; } } } private static void SetFieldIfPresent(object instance, string fieldName, object value) { if (instance == null) { return; } try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = instance.GetType().GetField(fieldName, bindingAttr); if (field != null && (value == null || field.FieldType.IsInstanceOfType(value))) { field.SetValue(instance, value); } } catch { } } private static void PrepareBearSaddleRuntimeRefs(Component saddle, GameObject bear) { if ((Object)(object)saddle == (Object)null) { return; } if ((Object)(object)bear == (Object)null) { Tameable componentInParent = saddle.GetComponentInParent<Tameable>(); if ((Object)(object)componentInParent != (Object)null) { bear = ((Component)componentInParent).gameObject; } } if (!((Object)(object)bear == (Object)null)) { SetFieldIfPresent(saddle, "m_character", bear.GetComponent<Character>()); SetFieldIfPresent(saddle, "m_nview", bear.GetComponent<ZNetView>()); SetFieldIfPresent(saddle, "m_tambable", bear.GetComponent<Tameable>()); SetFieldIfPresent(saddle, "m_monsterAI", bear.GetComponent<MonsterAI>()); } } private static Vector3 DivideVector(Vector3 a, Vector3 b) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) return new Vector3((Mathf.Abs(b.x) > 0.0001f) ? (a.x / b.x) : a.x, (Mathf.Abs(b.y) > 0.0001f) ? (a.y / b.y) : a.y, (Mathf.Abs(b.z) > 0.0001f) ? (a.z / b.z) : a.z); } private static GameObject EnsureBearSaddleVisual(Tameable tameable, ObjectDB db) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tameable == (Object)null || (Object)(object)((Component)tameable).gameObject == (Object)null || (Object)(object)db == (Object)null) { return null; } int instanceID = ((Object)((Component)tameable).gameObject).GetInstanceID(); if (saddleVisualCache.TryGetValue(instanceID, out var value) && !((Object)(object)value != (Object)null)) { saddleVisualCache.Remove(instanceID); } Transform val = FindVisualRoot(((Component)tameable).gameObject); if ((Object)(object)val == (Object)null) { return null; } GameObject itemPrefab = db.GetItemPrefab("SaddleLox"); if ((Object)(object)itemPrefab == (Object)null) { return null; } Transform val2 = FindChildRecursive(itemPrefab.transform, "attach"); if ((Object)(object)val2 == (Object)null) { if (Log != null) { Log.LogError((object)"[nick008-bear] SaddleLox/attach was not found."); } return null; } Transform val3 = FindChildRecursive(((Component)tameable).gameObject.transform, "Spine_02"); if ((Object)(object)val3 == (Object)null) { val3 = FindChildRecursive(((Component)tameable).gameObject.transform, "Chest"); } if ((Object)(object)val3 == (Object)null) { val3 = FindChildRecursive(((Component)tameable).gameObject.transform, "Spine_01"); } if ((Object)(object)val3 == (Object)null) { val3 = val; } Transform val4 = FindChildRecursive(val, "nick008_BearSaddleVisual"); if ((Object)(object)val4 != (Object)null) { Transform transform = ((Component)tameable).gameObject.transform; val4.localScale = val2.localScale; val4.position = val3.position + transform.up * -0.05f + transform.forward * -0.15f + transform.right * 0.02f; Quaternion rotation = transform.rotation * val2.localRotation * Quaternion.Euler(270f, 0f, 90f) * Quaternion.AngleAxis(-90f, Vector3.forward) * Quaternion.AngleAxis(90f, Vector3.right); val4.rotation = rotation; saddleVisualCache[instanceID] = ((Component)val4).gameObject; return ((Component)val4).gameObject; } GameObject val5 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val); ((Object)val5).name = "nick008_BearSaddleVisual"; Rigidbody[] componentsInChildren = val5.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } Collider[] componentsInChildren2 = val5.GetComponentsInChildren<Collider>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren2[j]); } } Vector3 localScale = val2.localScale; val5.transform.localScale = localScale; Transform transform2 = ((Component)tameable).gameObject.transform; val5.transform.position = val3.position + transform2.up * -0.05f + transform2.forward * -0.15f + transform2.right * 0.02f; Quaternion rotation2 = transform2.rotation * val2.localRotation * Quaternion.Euler(270f, 0f, 90f) * Quaternion.AngleAxis(-90f, Vector3.forward) * Quaternion.AngleAxis(90f, Vector3.right); val5.transform.rotation = rotation2; Renderer[] componentsInChildren3 = val5.GetComponentsInChildren<Renderer>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { if ((Object)(object)componentsInChildren3[k] != (Object)null) { componentsInChildren3[k].enabled = true; ((Component)componentsInChildren3[k]).gameObject.SetActive(true); } } val5.SetActive(false); saddleVisualCache[instanceID] = val5; if (Log != null) { Log.LogInfo((object)("[nick008-bear] Created ONE visual SaddleLox/attach clone for Bjorn id=" + instanceID + ", renderers=" + componentsInChildren3.Length + ", attachScale=" + localScale)); } return val5; } private static void RefreshLoadedBearSaddles(ObjectDB db) { Tameable[] array = Object.FindObjectsOfType<Tameable>(); foreach (Tameable tameable in array) { if (IsBearTameable(tameable)) { bool flag = BearHasSaddle(tameable); if (flag) { EnsureBearSaddleVisual(tameable, db); } SetBearSaddleVisual(tameable, flag); } } } private static Sadle GetControlledBearSaddle(Player player) { if ((Object)(object)player == (Object)null) { return null; } try { IDoodadController doodadController = player.GetDoodadController(); Sadle val = (Sadle)(object)((doodadController is Sadle) ? doodadController : null); if ((Object)(object)val == (Object)null) { return null; } Character character = val.GetCharacter(); if ((Object)(object)character == (Object)null || (Object)(object)((Component)character).gameObject == (Object)null) { return null; } Tameable component = ((Component)character).GetComponent<Tameable>(); return IsBearTameable(component) ? val : null; } catch { return null; } } private static void RestoreLevel3MountedScale() { //IL_0077: 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) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)level3ScaledBear != (Object)null && (Object)(object)((Component)level3ScaledBear).gameObject != (Object)null) { ((Component)level3ScaledBear).transform.localScale = level3OriginalLocalScale; if (Log != null) { ManualLogSource log = Log; Vector3 lossyScale = ((Component)level3ScaledBear).transform.lossyScale; log.LogInfo((object)("[nick008-bear] 1.1.4 FINAL: restored 2-star bear scale after dismount to " + ((Vector3)(ref lossyScale)).ToString("F2"))); } } } catch { } finally { level3ScaledBear = null; level3OriginalLocalScale = Vector3.one; } } private static void ApplyLevel3MountedScale(Character mount) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)mount == (Object)null || mount.GetLevel() < 3) { RestoreLevel3MountedScale(); return; } if ((Object)(object)level3ScaledBear != (Object)null && (Object)(object)level3ScaledBear != (Object)(object)mount) { RestoreLevel3MountedScale(); } if ((Object)(object)level3ScaledBear == (Object)null) { level3ScaledBear = mount; level3OriginalLocalScale = ((Component)mount).transform.localScale; float x = ((Component)mount).transform.lossyScale.x; if (x > 1.251f) { float num = 1.25f / x; ((Component)mount).transform.localScale = ((Component)mount).transform.localScale * num; } if (Log != null) { ManualLogSource log = Log; string text = ((Vector3)(ref level3OriginalLocalScale)).ToString("F2"); Vector3 lossyScale = ((Component)mount).transform.lossyScale; log.LogInfo((object)("[nick008-bear] 1.1.4 FINAL: mounted level-3 bear scale " + text + " -> world " + ((Vector3)(ref lossyScale)).ToString("F2"))); } } } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] 1.1.3 scale test failed: " + ex.Message)); } } } private static void RunLevel3MovementFallback(Character mount) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)mount == (Object)null || ((Object)mount).GetInstanceID() != mountedBearControlId || mount.GetLevel() < 3 || Time.time - mountedBearControlTime > 0.2f || ((Vector3)(ref mountedBearDesiredDirection)).sqrMagnitude < 0.01f) { return; } Tameable component = ((Component)mount).GetComponent<Tameable>(); Rigidbody val = null; FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_body"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(mount); val = (Rigidbody)((value is Rigidbody) ? value : null); } if ((Object)(object)val == (Object)null) { val = ((Component)mount).GetComponent<Rigidbody>(); } if (!IsBearTameable(component) || (Object)(object)val == (Object)null) { return; } int instanceID = ((Object)mount).GetInstanceID(); if (!mountedBearDiagnosticsLogged.Contains(instanceID)) { mountedBearDiagnosticsLogged.Add(instanceID); if (Log != null) { ManualLogSource log = Log; object[] array = new object[14] { "[nick008-bear] 1.1.3 LEVEL3 DIAG: level=", mount.GetLevel(), ", walk=", mount.m_walkSpeed.ToString("0.00"), ", speed=", mount.m_speed.ToString("0.00"), ", run=", mount.m_runSpeed.ToString("0.00"), ", bodyKinematic=", val.isKinematic, ", constraints=", val.constraints, ", rootScale=", null }; Vector3 lossyScale = ((Component)mount).transform.lossyScale; array[13] = ((Vector3)(ref lossyScale)).ToString("F2"); log.LogInfo((object)string.Concat(array)); } } Vector3 linearVelocity = val.linearVelocity; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(linearVelocity.x, 0f, linearVelocity.z); if (!(((Vector3)(ref val2)).sqrMagnitude > 0.09f)) { float num = (mountedBearWantsRun ? Mathf.Max(mount.m_runSpeed, 7f) : Mathf.Max(mount.m_speed, 3f)); Vector3 val3 = ((Vector3)(ref mountedBearDesiredDirection)).normalized * num; linearVelocity.x = val3.x; linearVelocity.z = val3.z; val.linearVelocity = linearVelocity; } } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] 1.1.3 level3 Rigidbody fallback failed: " + ex.Message)); } } } private void FixedUpdate() { try { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { RestoreLevel3MountedScale(); return; } Sadle controlledBearSaddle = GetControlledBearSaddle(localPlayer); if ((Object)(object)controlledBearSaddle == (Object)null) { RestoreLevel3MountedScale(); return; } Character character = controlledBearSaddle.GetCharacter(); ApplyLevel3MountedScale(character); RunLevel3MovementFallback(character); } catch (Exception ex) { if (Log != null) { Log.LogWarning((object)("[nick008-bear] 1.1.3 plugin FixedUpdate fallback failed: " + ex.Message)); } } } private static void ConfigureFoodsOnPrefab(GameObject bear, ObjectDB db) { if (!((Object)(object)bear == (Object)null) && !((Object)(object)db == (Object)null)) { MonsterAI component = bear.GetComponent<MonsterAI>(); if (!((Object)(object)component == (Object)null)) { component.m_consumeItems = BuildFoodList(db); component.m_consumeRange = 1.8f; component.m_consumeSearchInterval = 10f; component.m_consumeSearchRange = 15f; } } } private static void UpdateLoadedBearFoods(ObjectDB db) { MonsterAI[] array = Object.FindObjectsOfType<MonsterAI>(); foreach (MonsterAI val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null)) { string text = ((Object)((Component)val).gameObject).name ?? string.Empty; if (text.StartsWith("Bjorn", StringComparison.OrdinalIgnoreCase) && (val.m_consumeItems == null || val.m_consumeItems.Count == 0)) { val.m_consumeItems = BuildFoodList(db); val.m_consumeRange = 1.8f; val.m_consumeSearchInterval = 10f; val.m_consumeSearchRange = 15f; } } } } private static List<ItemDrop> BuildFoodList(ObjectDB db) { List<ItemDrop> list = new List<ItemDrop>(); for (int i = 0; i < FoodPrefabNames.Length; i++) { GameObject itemPrefab = db.GetItemPrefab(FoodPrefabNames[i]); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && !list.Contains(component)) { list.Add(component); } } } return list; } private static GameObject EnsureDedicatedBearSaddle(ObjectDB db, ZNetScene scene) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if ((Object)(object)db == (Object)null || (Object)(object)scene == (Object)null || (Object)(object)Instance == (Object)null) { return null; } try { GameObject val = db.GetItemPrefab("nick008_BearSaddleItem"); if ((Object)(object)val == (Object)null) { GameObject itemPrefab = db.GetItemPrefab("SaddleLox"); if ((Object)(object)itemPrefab == (Object)null) { return null; } if ((Object)(object)Instance.customSaddlePrefabRoot == (Object)null) { Instance.customSaddlePrefabRoot = new GameObject("nick008_bear_saddle_prefab_root"); Instance.customSaddlePrefabRoot.transform.SetParent(((Component)Instance).transform, false); Instance.customSaddlePrefabRoot.SetActive(false); } val = Object.Instantiate<GameObject>(itemPrefab, Instance.customSaddlePrefabRoot.transform); ((Object)val).name = "nick008_BearSaddleItem"; ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Object.DestroyImmediate((Object)(object)val); Log.LogError((object)"[nick008-bear] Could not clone SaddleLox ItemDrop for Bear Saddle."); return null; } component.m_itemData.m_shared.m_name = "Bear Saddle"; component.m_itemData.m_shared.m_description = "A sturdy saddle made for riding a tamed bear."; RegisterItemInObjectDB(db, val); RegisterPrefabInZNetScene(scene, val); Log.LogInfo((object)"[nick008-bear] 1.2.1 created dedicated Bear Saddle item from vanilla SaddleLox."); } else { RegisterPrefabInZNetScene(scene, val); } EnsureBearSaddleRecipe(db, scene, val); int instanceID = ((Object)db).GetInstanceID(); if (customSaddleConfiguredDbId != instanceID) { customSaddleConfiguredDbId = instanceID; RefreshKnownRecipesForLocalPlayer(); } return val; } catch (Exception ex) { Log.LogError((object)("[nick008-bear] 1.2.1 Bear Saddle registration failed: " + ex)); return null; } } private static void RegisterItemInObjectDB(ObjectDB db, GameObject itemPrefab) { if (!((Object)(object)db == (Object)null) && !((Object)(object)itemPrefab == (Object)null)) { FieldInfo fieldInfo = AccessTools.Field(typeof(ObjectDB), "m_items"); IList list = ((fieldInfo != null) ? (fieldInfo.GetValue(db) as IList) : null); if (list != null && !list.Contains(itemPrefab)) { list.Add(itemPrefab); } MethodInfo methodInfo = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(db, null); } } } private static void RegisterPrefabInZNetScene(ZNetScene scene, GameObject prefab) { if (!((Object)(object)scene == (Object)null) && !((Object)(object)prefab == (Object)null)) { if (!scene.m_prefabs.Contains(prefab)) { scene.m_prefabs.Add(prefab); } FieldInfo fieldInfo = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); IDictionary dictionary = ((fieldInfo != null) ? (fieldInfo.GetValue(scene) as IDictionary) : null); if (dictionary != null) { int valheimStableHash = GetValheimStableHash("nick008_BearSaddleItem"); dictionary[valheimStableHash] = prefab; } } } private static int GetValheimStableHash(string value) { try { Type type = AccessTools.TypeByName("StringExtensionMethods"); if (type != null) { MethodInfo method = type.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (method != null) { return (int)method.Invoke(null, new object[1] { value }); } } } catch { } int num = 5381; int num2 = num; for (int i = 0; i < value.Length; i += 2) { num = ((num << 5) + num) ^ value[i]; if (i == value.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ value[i + 1]; } return num + num2 * 1566083941; } private static void EnsureBearSaddleRecipe(ObjectDB db, ZNetScene scene, GameObject customPrefab) { //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown if ((Object)(object)db == (Object)null || (Object)(object)scene == (Object)null || (Object)(object)customPrefab == (Object)null) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ObjectDB), "m_recipes"); IList list = ((fieldInfo != null) ? (fieldInfo.GetValue(db) as IList) : null); if (list == null) { Log.LogError((object)"[nick008-bear] ObjectDB.m_recipes was not found; Bear Saddle recipe cannot be added."); return; } for (int i = 0; i < list.Count; i++) { object? obj = list[i]; Recipe val = (Recipe)((obj is Recipe) ? obj : null); if ((Object)(object)val != (Object)null && ((Object)val).name == "Recipe_nick008_BearSaddle") { return; } } ItemDrop component = customPrefab.GetComponent<ItemDrop>(); GameObject val2 = ResolveItemPrefab(db, "BronzeNails"); GameObject val3 = ResolveBearHidePrefab(db); GameObject val4 = ResolveItemPrefab(db, "FineWood"); GameObject prefab = scene.GetPrefab("piece_workbench"); ItemDrop val5 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<ItemDrop>() : null); ItemDrop val6 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<ItemDrop>() : null); ItemDrop val7 = (((Object)(object)val4 != (Object)null) ? val4.GetComponent<ItemDrop>() : null); CraftingStation val8 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CraftingStation>() : null); if ((Object)(object)component == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null || (Object)(object)val7 == (Object)null || (Object)(object)val8 == (Object)null) { Log.LogWarning((object)("[nick008-bear] Bear Saddle recipe waiting for resources/station. BronzeNails=" + ((Object)(object)val5 != (Object)null) + ", BearHide=" + ((Object)(object)val6 != (Object)null) + ", FineWood=" + ((Object)(object)val7 != (Object)null) + ", Workbench=" + ((Object)(object)val8 != (Object)null))); return; } Recipe val9 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val9).name = "Recipe_nick008_BearSaddle"; val9.m_item = component; val9.m_amount = 1; Requirement[] array = (Requirement[])(object)new Requirement[3]; Requirement val10 = new Requirement(); val10.m_resItem = val5; val10.m_amount = 20; array[0] = val10; Requirement val11 = new Requirement(); val11.m_resItem = val6; val11.m_amount = 5; array[1] = val11; Requirement val12 = new Requirement(); val12.m_resItem = val7; val12.m_amount = 10; array[2] = val12; val9.m_resources = array; SetFieldIfPresent(val9, "m_craftingStation", val8); SetFieldIfPresent(val9, "m_minStationLevel", 1); SetFieldIfPresent(val9, "m_enabled", true); list.Add(val9); Log.LogInfo((object)("[nick008-bear] 1.2.1 Bear Saddle recipe added: 20 Bronze Nails + 5 " + ((Object)val3).name + " + 10 Fine Wood at Workbench.")); } private static GameObject ResolveItemPrefab(ObjectDB db, params string[] prefabNames) { if ((Object)(object)db == (Object)null || prefabNames == null) { return null; } for (int i = 0; i < prefabNames.Length; i++) { GameObject itemPrefab = db.GetItemPrefab(prefabNames[i]); if ((Object)(object)itemPrefab != (Object)null) { return itemPrefab; } } return null; } private static GameObject ResolveBearHidePrefab(ObjectDB db) { GameObject val = ResolveItemPrefab(db, "BjornHide", "BearHide", "BjornPelt", "BearPelt", "BjornSkin", "BearSkin"); if ((Object)(object)val != (Object)null) { return val; } FieldInfo fieldInfo = AccessTools.Field(typeof(ObjectDB), "m_items"); IList list = ((fieldInfo != null) ? (fieldInfo.GetValue(db) as IList) : null); if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { object? obj = list[i]; GameObject val2 = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val2 == (Object)null)) { ItemDrop component = val2.GetComponent<ItemDrop>(); string text = ((((Object)val2).name != null) ? ((Object)val2).name.ToLowerInvariant() : string.Empty); string text2 = (((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_name != null) ? component.m_itemData.m_shared.m_name.ToLowerInvariant() : string.Empty); bool flag = text.Contains("bjorn") || text.Contains("bear") || text2.Contains("bjorn") || text2.Contains("bear"); bool flag2 = text.Contains("hide") || text.Contains("pelt") || text.Contains("skin") || text2.Contains("hide") || text2.Contains("pelt") || text2.Contains("skin"); if (flag && flag2) { Log.LogInfo((object)("[nick008-bear] Bear hide auto-detected as prefab '" + ((Object)val2).name + "'.")); return val2; } } } return null; } private static void ApplyDedicatedBearSaddleToBears(ZNetScene scene, ItemDrop bearSaddleItem) { if ((Object)(object)scene == (Object)null || (Object)(object)bearSaddleItem == (Object)null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeof(Tameable).GetField("m_saddleItem", bindingAttr); if (field == null) { return; } GameObject prefab = scene.GetPrefab("Bjorn"); Tameable val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Tameable>() : null); if ((Object)(object)val != (Object)null) { field.SetValue(val, bearSaddleItem); } Tameable[] array = Object.FindObjectsOfType<Tameable>(); for (int i = 0; i < array.Length; i++) { if (IsBearTameable(array[i])) { field.SetValue(array[i], bearSaddleItem); } } } private static void RefreshKnownRecipesForLocalPlayer() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } string[] array = new string[2] { "UpdateKnownRecipesList", "UpdateKnownRecipes" }; for (int i = 0; i < array.Length; i++) { try { MethodInfo methodInfo = AccessTools.Method(typeof(Player), array[i], (Type[])null, (Type[])null); if (methodInfo != null && methodInfo.GetParameters().Length == 0) { methodInfo.Invoke(localPlayer, null); break; } } catch { } } } private static bool SetupBearRiding(GameObject bear, GameObject lox, Tameable bearTame, Tameable loxTame) { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Expected O, but got Unknown //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeof(Tameable).GetField("m_saddleItem", bindingAttr); FieldInfo field2 = typeof(Tameable).GetField("m_saddle", bindingAttr); if (field == null || field2 == null) { Log.LogError((object)"[nick008-bear] Tameable saddle fields were not found."); return false; } object? value = field2.GetValue(loxTame); Component val = (Component)((value is Component) ? value : null); if ((Object)(object)val == (Object)null) { val = FindComponentByTypeName(lox, "Sadle"); } if ((Object)(object)val == (Object)null) { Log.LogError((object)"[nick008-bear] Vanilla Lox Sadle component was not found."); return false; } Transform val2 = FindVisualRoot(bear); if ((Object)(object)val2 == (Object)null) { Log.LogError((object)"[nick008-bear] Bjorn Visual root was not found."); return false; } Transform val3 = FindChildRecursive(bear.transform, "Spine_02"); if ((Object)(object)val3 == (Object)null) { val3 = FindChildRecursive(bear.transform, "Chest"); } if ((Object)(object)val3 == (Object)null) { val3 = FindChildRecursive(bear.transform, "Spine_01"); } if ((Object)(object)val3 == (Object)null) { val3 = val2; } Transform transform = bear.transform; Vector3 position = val3.position + transform.up * -0.1f + transform.forward * 1.2f + transform.right * 0.6f; Quaternion rotation = transform.rotation; Vector3 position2 = val3.position + transform.up * 0.55f + transform.forward * 0.3f + transform.right * 0.05f; Transform val4 = FindChildRecursive(bear.transform, "nick008_BearSaddle"); Component val5 = (((Object)(object)val4 != (Object)null) ? ((Component)val4).GetComponent(((object)val).GetType()) : null); if ((Object)(object)val5 == (Object)null) { GameObject val6 = Object.Instantiate<GameObject>(val.gameObject, bear.transform); ((Object)val6).name = "nick008_BearSaddle"; val6.SetActive(false); Renderer[] componentsInChildren = val6.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } val5 = val6.GetComponent(((object)val).GetType()); if ((Object)(object)val5 == (Object)null) { Object.DestroyImmediate((Object)(object)val6); Log.LogError((object)"[nick008-bear] Lox Sadel clone lost its Sadle component."); return false; } } val5.transform.SetParent(bear.transform, true); val5.transform.position = position; val5.transform.rotation = rotation; val5.transform.localScale = Vector3.one; SetFieldIfPresent(val5, "m_maxUseRange", 12f); SetFieldIfPresent(val5, "m_hoverText", "Bear Saddle"); Transform val7 = FindChildRecursive(bear.transform, "nick008_BearMountPoint"); if ((Object)(object)val7 == (Object)null) { GameObject val8 = new GameObject("nick008_BearMountPoint"); val7 = val8.transform; } val7.SetParent(bear.transform, true); val7.position = position2; val7.rotation = rotation; val7.localScale = Vector3.one; SetFieldIfPresent(val5, "m_attachPoint", val7); PrepareBearSaddleRuntimeRefs(val5, bear); field.SetValue(bearTame, field.GetValue(loxTame)); field2.SetValue(bearTame, val5); Collider[] componentsInChildren2 = val5.GetComponentsInChildren<Collider>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { componentsInChildren2[j].enabled = false; } } Log.LogInfo((object)("[nick008-bear] 1.1.4 FINAL riding setup. disabled logical saddle colliders=" + componentsInChildren2.Length + ", logical saddle distance from bear root=" + Vector3.Distance(bear.transform.position, val5.transform.position).ToString("0.00") + "m, rider mountPoint distance=" + Vector3.Distance(bear.transform.position, val7.position).ToString("0.00") + "m, colliders=" + componentsInChildren2.Length)); return true; } catch (Exception ex) { Log.LogError((object)("[nick008-bear] Bear riding setup failed: " + ex)); return false; } } private static Transform FindVisualRoot(GameObject creature) { if ((Object)(object)creature == (Object)null) { return null; } Transform val = creature.transform.Find("Visual"); if (!((Object)(object)val != (Object)null)) { return creature.transform; } return val; } private static Component FindComponentByTypeName(GameObject root, string typeName) { if ((Object)(object)root == (Object)null) { return null; } Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == typeName) { return val; } } return null; } private static Transform FindChildRecursive(Transform root, string wantedName) { if ((Object)(object)root == (Object)null) { return null; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == wantedName) { return componentsInChildren[i]; } } return null; } private static float CalculateSizeRatio(Transform bearVisual, Transform loxVisual) { float rendererHeight = GetRendererHeight(bearVisual); float rendererHeight2 = GetRendererHeight(loxVisual); if (rendererHeight > 0.1f && rendererHeight2 > 0.1f) { return Mathf.Clamp(rendererHeight / rendererHeight2, 0.45f, 0.85f); } return 0.65f; } private static float GetRendererHeight(Transform root) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0056: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true); bool flag = false; Bounds val = default(Bounds); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } string text = ((Object)((Component)val2).gameObject).name ?? string.Empty; if (text.IndexOf("saddle", StringComparison.OrdinalIgnoreCase) < 0) { if (!flag) { val = val2.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val2.bounds); } } } if (!flag) { return 0f; } return ((Bounds)(ref val)).size.y; } private static GameObject FindPrefabInSceneList(ZNetScene scene, string prefabName) { if ((Object)(object)scene == (Object)null || scene.m_prefabs == null) { return null; } for (int i = 0; i < scene.m_prefabs.Count; i++) { GameObject val = scene.m_prefabs[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == prefabName) { return val; } } return null; } private static void CopyPublicFields(Component destination, Component source) { if ((Object)(object)destination == (Object)null || (Object)(object)source == (Object)null) { return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public; FieldInfo[] fields = ((object)source).GetType().GetFields(bindingAttr); Type type = ((object)destination).GetType(); foreach (FieldInfo fieldInfo in fields) { FieldInfo field = type.GetField(fieldInfo.Name, bindingAttr); if (!(field == null) && !field.IsInitOnly && (field.FieldType.IsAssignableFrom(fieldInfo.FieldType) || fieldInfo.FieldType.IsAssignableFrom(field.FieldType))) { try { field.SetValue(destination, fieldInfo.GetValue(source)); } catch { } } } } } [HarmonyPatch] internal static class BearCubButcherProtectionPatch { private const string CubPrefabName = "nick008_BearCub"; private static bool loggedBlockedHit; private static MethodBase TargetMethod() { MethodInfo[] methods = typeof(Character).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "Damage")) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.Name == "HitData") { return methodInfo; } } } return null; } [HarmonyPrefix] private static bool Prefix(Character __instance, object __0) { try { if (!IsCub(__instance) || !IsButcherKnifeHit(__0)) { return true; } if (!loggedBlockedHit && Nick008TameableBearPlugin.Log != null) { loggedBlockedHit = true; Nick008TameableBearPlugin.Log.LogInfo((object)"[nick008tameablebear] Protected bear cub from butcher-knife hit."); } return false; } catch { return true; } } private static bool IsCub(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)((Component)character).gameObject == (Object)null) { return false; } string text = ((Object)((Component)character).gameObject).name ?? string.Empty; if (!text.Equals("nick008_BearCub", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("nick008_BearCub(", StringComparison.OrdinalIgnoreCase)) { return text.StartsWith("nick008_BearCub ", StringComparison.OrdinalIgnoreCase); } return true; } private static bool IsButcherKnifeHit(object hit) { if (hit == null) { return false; } object obj = InvokeNoArgMethod(hit, "GetAttacker"); if (obj == null || !IsTypeOrBaseNamed(obj.GetType(), "Player")) { return false; } object obj2 = InvokeNoArgMethod(obj, "GetCurrentWeapon"); if (obj2 == null) { return false; } object fieldValue = GetFieldValue(obj2, "m_dropPrefab"); GameObject val = (GameObject)((fieldValue is GameObject) ? fieldValue : null); if ((Object)(object)val != (Object)null && LooksLikeButcherKnife(((Object)val).name)) { return true; } object fieldValue2 = GetFieldValue(obj2, "m_shared"); object fieldValue3 = GetFieldValue(fieldValue2, "m_name"); if (fieldValue3 != null && LooksLikeButcherKnife(fieldValue3.ToString())) { return true; } return LooksLikeButcherKnife(obj2.ToString()); } private static bool LooksLikeButcherKnife(string value) { if (string.IsNullOrEmpty(value)) { return false; } string text = value.ToLowerInvariant(); if (!text.Contains("butcher") && !text.Contains("knifebutcher")) { return text.Contains("butcherknife"); } return true; } private static bool IsTypeOrBaseNamed(Type type, string name) { Type type2 = type; while (type2 != null) { if (string.Equals(type2.Name, name, StringComparison.OrdinalIgnoreCase)) { return true; } type2 = type2.BaseType; } return false; } private static object InvokeNoArgMethod(object instance, string methodName) { if (instance == null) { return null; } Type type = instance.GetType(); while (type != null) { MethodInfo method = type.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method != null) { return method.Invoke(instance, null); } type = type.BaseType; } return null; } private static object GetFieldValue(object instance, string fieldName) { if (instance == null) { return null; } Type type = instance.GetType(); while (type != null) { FieldInfo field = type.GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(instance); } type = type.BaseType; } return null; } }