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 Altar of the Pack v0.1.2
plugins/WolfShrine/WolfShrine.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("WolfShrine")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.2.0")] [assembly: AssemblyInformationalVersion("0.1.2")] [assembly: AssemblyProduct("WolfShrine")] [assembly: AssemblyTitle("WolfShrine")] [assembly: AssemblyVersion("0.1.2.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace WolfShrine { internal static class BlessedWolves { internal sealed class Growth { internal Character Source; internal Character Adult; internal float Factor; internal float Fraction; internal Vector3 Position; } internal const string BonusKey = "wolfshrine.health"; internal const string BirthKey = "wolfshrine.birth"; internal const string OriginKey = "wolfshrine.origin"; [ThreadStatic] internal static Growth? Growing; internal static bool FromShrine(Character? character) { if (character == null || !IsWolf(character)) { return false; } ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { if (!component.GetZDO().GetBool("wolfshrine.origin", false) && !(component.GetZDO().GetFloat("wolfshrine.health", 0f) >= 1f)) { return component.GetZDO().GetString("wolfshrine.birth", "").Length > 0; } return true; } return false; } internal static bool IsWolf(Character character) { if (Object.op_Implicit((Object)(object)character)) { if (!(((Object)character).name == "Wolf") && !(((Object)character).name == "Wolf(Clone)") && !(((Object)character).name == "Wolf_cub")) { return ((Object)character).name == "Wolf_cub(Clone)"; } return true; } return false; } internal static float Bonus(Character character) { if (!IsWolf(character)) { return 1f; } ZNetView component = ((Component)character).GetComponent<ZNetView>(); float num = ((Object.op_Implicit((Object)(object)component) && component.IsValid()) ? component.GetZDO().GetFloat("wolfshrine.health", 1f) : 1f); if (!(num >= 1f) || !(num <= 10f) || float.IsNaN(num)) { return 1f; } return num; } internal static void Mark(Character character, float factor) { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (!IsWolf(character) || !Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner()) { throw new InvalidOperationException("Shrine wolf is not a valid owned wolf."); } component.GetZDO().Set("wolfshrine.health", factor); component.GetZDO().Set("wolfshrine.origin", true); } } [HarmonyPatch(typeof(Character), "GetMaxHealthBase")] internal static class ShrineWolfHealth { private static void Postfix(Character __instance, ref float __result) { __result = RitualPolicy.Health(__result, BlessedWolves.Bonus(__instance)); } } [HarmonyPatch(typeof(Growup), "GrowUpdate")] internal static class PreserveShrineGrowth { private static void Prefix(Growup __instance, out BlessedWolves.Growth? __state) { //IL_0090: 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) __state = BlessedWolves.Growing; Character component = ((Component)__instance).GetComponent<Character>(); ZNetView component2 = ((Component)__instance).GetComponent<ZNetView>(); float factor = (Object.op_Implicit((Object)(object)component) ? BlessedWolves.Bonus(component) : 1f); if (BlessedWolves.FromShrine(component)) { __instance.m_inheritTame = true; } BlessedWolves.Growing = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2) && component2.IsValid() && component2.IsOwner() && BlessedWolves.FromShrine(component)) ? new BlessedWolves.Growth { Source = component, Factor = factor, Fraction = Mathf.Clamp01(component.GetHealthPercentage()), Position = ((Component)component).transform.position } : null); } private static void Finalizer(BlessedWolves.Growth? __state) { BlessedWolves.Growing = __state; } } [HarmonyPatch(typeof(Character), "SetLevel")] internal static class InheritShrineHealth { private static void Prefix(Character __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) BlessedWolves.Growth growing = BlessedWolves.Growing; if (growing != null && !((Object)(object)__instance == (Object)(object)growing.Source) && BlessedWolves.IsWolf(__instance) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Growup>())) { Vector3 val = ((Component)__instance).transform.position - growing.Position; if (!(((Vector3)(ref val)).sqrMagnitude > 4f) && (!Object.op_Implicit((Object)(object)growing.Adult) || !((Object)(object)growing.Adult != (Object)(object)__instance))) { BlessedWolves.Mark(__instance, growing.Factor); growing.Adult = __instance; } } } private static void Postfix(Character __instance) { BlessedWolves.Growth growing = BlessedWolves.Growing; if (growing != null && (Object)(object)growing.Adult == (Object)(object)__instance) { __instance.SetHealth(__instance.GetMaxHealth() * growing.Fraction); } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] internal static class ShrinePopupController { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(PlayerController __instance, ref bool __result) { if (WolfAltar.PopupOpen && (Object)(object)((Component)__instance).GetComponent<Player>() == (Object)(object)Player.m_localPlayer) { __result = false; } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class ShrinePopupPlayer { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Player __instance, ref bool __result) { if (WolfAltar.PopupOpen && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = false; } } } [HarmonyPatch(typeof(Piece), "CanBeRemoved")] internal static class KeepActiveAltar { private static bool Prefix(Piece __instance, ref bool __result) { WolfAltar component = ((Component)__instance).GetComponent<WolfAltar>(); if (!Object.op_Implicit((Object)(object)component) || !component.Busy) { return true; } __result = false; return false; } } [BepInPlugin("com.jason.wolfshrine", "Altar of the Pack", "0.1.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Id = "com.jason.wolfshrine"; public const string Version = "0.1.2"; internal static ManualLogSource Log; internal static ConfigEntry<string>[] Recipes; internal static ConfigEntry<float> HealthBonus; internal static ConfigEntry<float> RitualSeconds; internal static ConfigEntry<float> Cooldown; private Harmony patches; private void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; Recipes = new ConfigEntry<string>[3] { ((BaseUnityPlugin)this).Config.Bind<string>("Offerings", "ZeroStar", "WolfMeat:5,WolfPelt:2,BoneFragments:5", new ConfigDescription("0-star cub offering, exact prefab:amount pairs. Server synchronized.", (AcceptableValueBase)null, new object[1] { val })), ((BaseUnityPlugin)this).Config.Bind<string>("Offerings", "OneStar", "WolfMeat:10,WolfPelt:4,WolfFang:2,TrophyWolf:1,Silver:2", new ConfigDescription("1-star cub offering.", (AcceptableValueBase)null, new object[1] { val })), ((BaseUnityPlugin)this).Config.Bind<string>("Offerings", "TwoStar", "WolfMeat:20,WolfPelt:8,WolfFang:5,TrophyWolf:2,Silver:5", new ConfigDescription("2-star cub offering.", (AcceptableValueBase)null, new object[1] { val })) }; HealthBonus = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "ShrineWolfHealthMultiplier", 3f, new ConfigDescription("Health relative to an ordinary wolf of the same star tier. Stored on each shrine-born cub; follows it into adulthood. Damage unchanged; wild/bred wolves unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[1] { val })); RitualSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "RitualSeconds", 6f, new ConfigDescription("Delay before the cub appears; blocked exits wait without consuming again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), new object[1] { val })); Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "CooldownSeconds", 60f, new ConfigDescription("Per-shrine cooldown after birth.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), new object[1] { val })); patches = new Harmony("com.jason.wolfshrine"); patches.PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += ShrinePrefab.Register; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Altar of the Pack 0.1.2 loaded: born-tame 0/1/2-star cubs; default 3x health through adulthood."); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= ShrinePrefab.Register; Harmony obj = patches; if (obj != null) { obj.UnpatchSelf(); } } private void Update() { if (WolfAltar.PopupOpen && (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !UnifiedPopup.IsVisible())) { WolfAltar.PopupOpen = false; } WolfUnlock.Update(); } } internal static class RitualPolicy { internal const int MaxTier = 2; internal static bool Tier(int tier) { if (tier >= 0) { return tier <= 2; } return false; } internal static int Level(int tier) { if (!Tier(tier)) { throw new ArgumentOutOfRangeException("tier"); } return tier + 1; } internal static float Health(float native, float factor) { float num = native * factor; if (!(native > 0f) || !(factor >= 1f) || !(factor <= 10f) || float.IsNaN(num) || float.IsInfinity(num)) { return native; } return num; } internal static Dictionary<string, int>? Recipe(string value) { Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal); string[] array = value.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Trim().Split(new char[1] { ':' }); if (array2.Length != 2 || array2[0].Length == 0 || array2[0].Any((char c) => !char.IsLetterOrDigit(c) && c != '_') || !int.TryParse(array2[1], NumberStyles.None, CultureInfo.InvariantCulture, out var result) || result < 1 || result > 999 || dictionary.ContainsKey(array2[0])) { return null; } dictionary.Add(array2[0], result); } if (dictionary.Count <= 0 || dictionary.Count > 12) { return null; } return dictionary; } internal static int[]? Debit(string[] identities, int[] amounts, IReadOnlyDictionary<string, int> costs) { if (identities.Length != amounts.Length || amounts.Any((int a) => a <= 0) || costs.Count == 0 || costs.Any<KeyValuePair<string, int>>((KeyValuePair<string, int> p) => p.Key.Length == 0 || p.Value <= 0)) { return null; } int[] array = new int[amounts.Length]; foreach (KeyValuePair<string, int> cost in costs) { int num = cost.Value; for (int num2 = 0; num2 < identities.Length; num2++) { if (num <= 0) { break; } if (identities[num2] == cost.Key) { num -= (array[num2] = Math.Min(amounts[num2], num)); } } if (num > 0) { return null; } } return array; } internal static bool CanReserve(bool owner, bool access, bool alive, double distanceSquared, int tier, bool pending, double cooldown, double lease, double now) { if (owner && access && alive && distanceSquared >= 0.0 && distanceSquared <= 16.0 && Tier(tier) && !pending && cooldown <= now) { return lease <= now; } return false; } } internal static class ShrinePrefab { internal const string Name = "WolfShrine_AltarOfThePack"; internal static void Register() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_033e: 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_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= Register; try { GameObject prefab = PrefabManager.Instance.GetPrefab("TrophyWolf"); GameObject prefab2 = PrefabManager.Instance.GetPrefab("Wolf_cub"); if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)prefab2) || !Object.op_Implicit((Object)(object)prefab2.GetComponent<Character>()) || !Object.op_Implicit((Object)(object)prefab2.GetComponent<Growup>())) { throw new InvalidOperationException("Native wolf cub/trophy prefabs are missing."); } PieceConfig val = new PieceConfig(); val.Name = "Altar of the Pack"; val.Description = "Unlock by taming a wolf, or petting an existing ordinary tame wolf. Offer wolf remains to summon a born-tamed, hardy wolf cub. All three star tiers available. Use to review; alternate use changes the selected tier."; val.PieceTable = "Hammer"; val.Category = "Crafting"; val.CraftingStation = ""; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("Stone", 20, 0, true), new RequirementConfig("Silver", 5, 0, true), new RequirementConfig("TrophyWolf", 1, 0, true) }; CustomPiece val2 = new CustomPiece("WolfShrine_AltarOfThePack", "stone_floor_2x2", val); GameObject piecePrefab = val2.PiecePrefab; piecePrefab.GetComponent<Piece>().m_icon = prefab.GetComponent<ItemDrop>().m_itemData.GetIcon(); piecePrefab.GetComponent<Piece>().m_craftingStation = null; piecePrefab.GetComponent<Piece>().m_groundOnly = false; WearNTear component = piecePrefab.GetComponent<WearNTear>(); MeshFilter val3 = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_new)) ? component.m_new : piecePrefab).GetComponentsInChildren<MeshFilter>(true).Where(delegate(MeshFilter f) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)f.sharedMesh) && Object.op_Implicit((Object)(object)((Component)f).GetComponent<MeshRenderer>())) { Bounds bounds = f.sharedMesh.bounds; if (((Bounds)(ref bounds)).size.x > 0.001f) { bounds = f.sharedMesh.bounds; if (((Bounds)(ref bounds)).size.y > 0.001f) { bounds = f.sharedMesh.bounds; return ((Bounds)(ref bounds)).size.z > 0.001f; } } } return false; }).OrderByDescending(delegate(MeshFilter f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = f.sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude; }) .FirstOrDefault(); if (Object.op_Implicit((Object)(object)val3)) { StoneBlock(piecePrefab.transform, "Hewn altar body", val3, new Vector3(0f, 0.48f, 0f), new Vector3(1.42f, 0.52f, 1.04f), 0.72f); StoneBlock(piecePrefab.transform, "Offering capstone", val3, new Vector3(0f, 0.79f, -0.04f), new Vector3(1.66f, 0.18f, 1.25f), 0.8f); StoneBlock(piecePrefab.transform, "Wolf headstone", val3, new Vector3(0f, 1.18f, 0.43f), new Vector3(1.16f, 1.05f, 0.25f), 0.66f); } else { Plugin.Log.LogWarning((object)"Native stone mesh unavailable; retaining native altar base instead of preventing shrine registration."); } object obj = prefab.transform.Find("attach"); if (obj == null) { obj = prefab.transform.Find("visual"); if (obj == null) { Renderer componentInChildren = prefab.GetComponentInChildren<Renderer>(true); obj = ((componentInChildren != null) ? ((Component)componentInChildren).transform : null); } } if (!Object.op_Implicit((Object)obj)) { throw new InvalidOperationException("Wolf trophy has no safe detachable visual."); } GameObject val4 = Object.Instantiate<GameObject>(((Component)obj).gameObject, piecePrefab.transform, false); ((Object)val4).name = "Shrine wolf trophy"; val4.transform.localPosition = new Vector3(0f, Object.op_Implicit((Object)(object)val3) ? 1.28f : 0.6f, 0.19f); val4.transform.localRotation = Quaternion.Euler(0f, 180f, 0f); val4.transform.localScale = Vector3.one * 0.65f; MonoBehaviour[] componentsInChildren = val4.GetComponentsInChildren<MonoBehaviour>(true); for (int num = 0; num < componentsInChildren.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren[num]); } Collider[] componentsInChildren2 = val4.GetComponentsInChildren<Collider>(true); for (int num = 0; num < componentsInChildren2.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[num]); } Rigidbody[] componentsInChildren3 = val4.GetComponentsInChildren<Rigidbody>(true); for (int num = 0; num < componentsInChildren3.Length; num++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[num]); } Renderer[] componentsInChildren4 = val4.GetComponentsInChildren<Renderer>(true); foreach (Renderer obj2 in componentsInChildren4) { obj2.sharedMaterials = obj2.sharedMaterials.Select((Material m) => Matte(m, 1f)).ToArray(); } val4.SetActive(true); if (Object.op_Implicit((Object)(object)val3)) { Runes(piecePrefab.transform); } GameObject val5 = new GameObject("Shrine light"); val5.transform.SetParent(piecePrefab.transform, false); val5.transform.localPosition = new Vector3(0f, 1.05f, -0.48f); Light obj3 = val5.AddComponent<Light>(); obj3.color = new Color(0.16f, 0.42f, 0.66f); obj3.range = 1.6f; obj3.intensity = 0.12f; piecePrefab.AddComponent<WolfAltar>(); if (!PieceManager.Instance.AddPiece(val2)) { throw new InvalidOperationException("Shrine piece registration rejected."); } Plugin.Log.LogInfo((object)"Registered Altar of the Pack in Hammer/Crafting: wolf-taming unlock, no crafting station; native Wolf_cub verified."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Wolf shrine registration failed; no ritual is available. {arg}"); } } private static Material Matte(Material source, float shade) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0056: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)source)) { return source; } Material val = new Material(source) { name = "WolfShrine matte " + ((Object)source).name }; if (val.HasProperty("_Color")) { Color color = val.GetColor("_Color"); val.SetColor("_Color", new Color(color.r * shade, color.g * shade, color.b * shade, color.a)); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", Color.black); } if (val.HasProperty("_Glossiness")) { val.SetFloat("_Glossiness", 0.08f); } if (val.HasProperty("_Metallic")) { val.SetFloat("_Metallic", 0f); } val.DisableKeyword("_EMISSION"); return val; } private static void StoneBlock(Transform parent, string name, MeshFilter source, Vector3 centre, Vector3 size, float shade) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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) Mesh sharedMesh = source.sharedMesh; Bounds bounds = sharedMesh.bounds; if (((Bounds)(ref bounds)).size.x <= 0.001f || ((Bounds)(ref bounds)).size.y <= 0.001f || ((Bounds)(ref bounds)).size.z <= 0.001f) { throw new InvalidOperationException("Native stone mesh has invalid bounds."); } GameObject val = new GameObject(name) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(size.x / ((Bounds)(ref bounds)).size.x, size.y / ((Bounds)(ref bounds)).size.y, size.z / ((Bounds)(ref bounds)).size.z); val.transform.localScale = val2; val.transform.localPosition = centre - Vector3.Scale(((Bounds)(ref bounds)).center, val2); val.AddComponent<MeshFilter>().sharedMesh = sharedMesh; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)((Component)source).GetComponent<MeshRenderer>()).sharedMaterials.Select((Material m) => Matte(m, shade)).ToArray(); val.AddComponent<MeshCollider>().sharedMesh = sharedMesh; } private static void Runes(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_005d: Expected O, but got Unknown //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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default"); if (!Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogWarning((object)"Rune shader unavailable; retaining the stone/trophy altar without rune inlays."); return; } Material sharedMaterial = new Material(val) { name = "WolfShrine muted blue rune", color = new Color(0.12f, 0.48f, 0.64f) }; Vector2[][] array = new Vector2[4][] { (Vector2[])(object)new Vector2[4] { new Vector2(0f, 0f), new Vector2(0f, 0.18f), new Vector2(0.08f, 0.14f), new Vector2(0f, 0.1f) }, (Vector2[])(object)new Vector2[4] { new Vector2(0f, 0f), new Vector2(0f, 0.18f), new Vector2(0.08f, 0.15f), new Vector2(0.08f, 0f) }, (Vector2[])(object)new Vector2[3] { new Vector2(0f, 0f), new Vector2(0f, 0.18f), new Vector2(0.08f, 0.12f) }, (Vector2[])(object)new Vector2[6] { new Vector2(0f, 0f), new Vector2(0f, 0.18f), new Vector2(0.08f, 0.18f), new Vector2(0f, 0.18f), new Vector2(0f, 0.1f), new Vector2(0.06f, 0.1f) } }; for (int i = 0; i < array.Length; i++) { GameObject val2 = new GameObject("Carved pack rune " + i) { layer = ((Component)parent).gameObject.layer }; val2.transform.SetParent(parent, false); LineRenderer val3 = val2.AddComponent<LineRenderer>(); val3.useWorldSpace = false; ((Renderer)val3).sharedMaterial = sharedMaterial; val3.widthMultiplier = 0.018f; val3.positionCount = array[i].Length; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; for (int j = 0; j < array[i].Length; j++) { val3.SetPosition(j, new Vector3(-0.45f + (float)i * 0.28f + array[i][j].x, 0.46f + array[i][j].y, -0.545f)); } } } } public sealed class WolfAltar : MonoBehaviour, Hoverable, Interactable { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static PopupButtonCallback <>9__35_1; public static Func<string, bool> <>9__37_0; public static Func<KeyValuePair<string, int>, string> <>9__38_0; public static Func<ItemData, int> <>9__40_0; public static Func<ItemData, int> <>9__42_0; public static Func<ItemData, int> <>9__42_1; internal void <Interact>b__35_1() { UnifiedPopup.Pop(); PopupOpen = false; } internal bool <ValidRecipe>b__37_0(string id) { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { return Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(id)); } return false; } internal string <CostText>b__38_0(KeyValuePair<string, int> pair) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(pair.Key) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); return pair.Value + " " + (Object.op_Implicit((Object)(object)val2) ? Localization.instance.Localize(val2.m_itemData.m_shared.m_name) : pair.Key); } internal int <Offer>b__40_0(ItemData i) { return i.m_stack; } internal int <Commit>b__42_0(ItemData i) { return i.m_stack; } internal int <Commit>b__42_1(ItemData i) { return i.m_stack; } internal void <.cctor>b__53_0(Inventory inventory) { AccessTools.MethodDelegate<Action<Inventory, bool, bool>>(AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null), (object)null, true)(inventory, arg2: false, arg3: false); } } internal static bool PopupOpen; private const string Lease = "ws_lease"; private const string Holder = "ws_holder"; private const string Expiry = "ws_expiry"; private const string LeaseTier = "ws_lease_tier"; private const string Pending = "ws_pending"; private const string Due = "ws_due"; private const string Star = "ws_star"; private const string Bonus = "ws_bonus"; private const string Paid = "ws_paid"; private const string Next = "ws_next"; private static readonly Func<PrivateArea, bool> WardEnabled = AccessTools.MethodDelegate<Func<PrivateArea, bool>>(AccessTools.Method(typeof(PrivateArea), "IsEnabled", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<PrivateArea, Vector3, float, bool> WardInside = AccessTools.MethodDelegate<Func<PrivateArea, Vector3, float, bool>>(AccessTools.Method(typeof(PrivateArea), "IsInside", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<PrivateArea, long, bool> WardPermitted = AccessTools.MethodDelegate<Func<PrivateArea, long, bool>>(AccessTools.Method(typeof(PrivateArea), "IsPermitted", (Type[])null, (Type[])null), (object)null, true); private ZNetView view; private int selectedTier; private string request = ""; private bool answered; private bool granted; private bool requesting; private long expectedOwner; private float nextBirthCheck; private readonly HashSet<string> seen = new HashSet<string>(); private readonly Queue<string> history = new Queue<string>(); private static readonly Action<Inventory> InventoryChanged = delegate(Inventory inventory) { AccessTools.MethodDelegate<Action<Inventory, bool, bool>>(AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null), (object)null, true)(inventory, arg2: false, arg3: false); }; private static double Now => (double)ZNet.instance.GetTime().Ticks / 10000000.0; internal bool Busy { get { if (Object.op_Implicit((Object)(object)view) && view.IsValid()) { if (view.GetZDO().GetString("ws_pending", "").Length <= 0) { return TimeAt(view.GetZDO(), "ws_expiry") > Now; } return true; } return false; } } private static double TimeAt(ZDO data, string key) { return (double)data.GetLong(key, 0L) / 10000000.0; } private static void SetTime(ZDO data, string key, double time) { data.Set(key, (long)(time * 10000000.0)); } private void Awake() { view = ((Component)this).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)view) && view.IsValid()) { view.Register<string, int>("WS_Reserve", (Action<long, string, int>)Reserve); view.Register<string, bool>("WS_Granted", (Action<long, string, bool>)Response); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(RefundDestroyed)); } } } public string GetHoverName() { return "Altar of the Pack"; } public float GetHoverOffset() { return 1f; } public string GetHoverText() { if (!Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return GetHoverName(); } if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && !WolfUnlock.Has(Player.m_localPlayer)) { return "Altar of the Pack\nTame a wolf, or pet an existing ordinary tame wolf, to unlock this shrine."; } ZDO zDO = view.GetZDO(); if (zDO.GetString("ws_pending", "").Length > 0) { return GetHoverName() + "\nRitual in progress — keep the space beside the shrine clear."; } double num = TimeAt(zDO, "ws_next") - Now; string text = ((num > 0.0) ? $"\nResting: {Math.Ceiling(num)} seconds" : ""); return Localization.instance.Localize($"Altar of the Pack — {selectedTier}-star cub\nBorn tamed; {Plugin.HealthBonus.Value:0.#}× health through adulthood.\n{CostText(selectedTier)}{text}\n[<color=yellow>$KEY_Use</color>] Review offering\n[<color=yellow>$KEY_AltPlace + $KEY_Use</color>] Next star tier"); } public bool UseItem(Humanoid user, ItemData item) { return false; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown if (hold || (Object)(object)user != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)view) || !view.IsValid() || PopupOpen || requesting) { return false; } if (alt) { selectedTier = (selectedTier + 1) % 3; return true; } Player player = Player.m_localPlayer; if (!WolfUnlock.Has(player)) { Tell("Tame a wolf, or pet an existing ordinary tame wolf, before using the shrine."); return true; } if (!Access(player) || Busy || TimeAt(view.GetZDO(), "ws_next") > Now) { Tell("The shrine is busy, resting or ward-protected."); return true; } int tier = selectedTier; string recipe = Plugin.Recipes[tier].Value; if (!ValidRecipe(recipe)) { Tell("This offering configuration is invalid; nothing consumed."); return true; } PopupOpen = true; string text = $"Summon one born-tamed {tier}-star wolf cub?\n\nOffering from your inventory:\n{CostText(tier)}\n\nShrine-born wolves have {Plugin.HealthBonus.Value:0.#}× normal health for their star tier, including adulthood. Damage is unchanged.\n\nThe ritual takes {Plugin.RitualSeconds.Value:0} seconds."; PopupButtonCallback val = delegate { UnifiedPopup.Pop(); PopupOpen = false; if (Object.op_Implicit((Object)(object)this)) { ((MonoBehaviour)this).StartCoroutine(Offer(player, tier, recipe)); } }; object obj = <>c.<>9__35_1; if (obj == null) { PopupButtonCallback val2 = delegate { UnifiedPopup.Pop(); PopupOpen = false; }; <>c.<>9__35_1 = val2; obj = (object)val2; } UnifiedPopup.Push((PopupBase)new YesNoPopup("Altar of the Pack", text, val, (PopupButtonCallback)obj, false, true)); return true; } private static string ItemId(ItemData item) { if (!Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ""; } return Utils.GetPrefabName(item.m_dropPrefab); } private static bool ValidRecipe(string text) { return RitualPolicy.Recipe(text)?.Keys.All((string id) => Object.op_Implicit((Object)(object)ObjectDB.instance) && Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(id))) ?? false; } private static string CostText(int tier) { Dictionary<string, int> dictionary = RitualPolicy.Recipe(Plugin.Recipes[tier].Value); if (dictionary == null) { return "Invalid offering configuration"; } return string.Join(", ", dictionary.Select(delegate(KeyValuePair<string, int> pair) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(pair.Key) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); return pair.Value + " " + (Object.op_Implicit((Object)(object)val2) ? Localization.instance.Localize(val2.m_itemData.m_shared.m_name) : pair.Key); })); } private bool Access(Player player) { //IL_001e: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player) && WolfUnlock.Has(player) && !((Character)player).IsDead()) { Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > 16f)) { bool flag = false; bool flag2 = false; PrivateArea[] array = Object.FindObjectsByType<PrivateArea>((FindObjectsSortMode)0); foreach (PrivateArea val2 in array) { if (WardEnabled(val2) && WardInside(val2, ((Component)this).transform.position, 0f)) { if (((Component)val2).GetComponent<Piece>().GetCreator() == player.GetPlayerID() || WardPermitted(val2, player.GetPlayerID())) { flag = true; } else { flag2 = true; } } } if (!flag) { return !flag2; } return true; } } return false; } private IEnumerator Offer(Player player, int tier, string reviewedRecipe) { if (requesting || !Object.op_Implicit((Object)(object)player) || !Access(player) || !ValidRecipe(reviewedRecipe) || Plugin.Recipes[tier].Value != reviewedRecipe) { yield break; } Dictionary<string, int> costs = RitualPolicy.Recipe(reviewedRecipe); ItemData[] source = ((Humanoid)player).GetInventory().GetAllItems().ToArray(); if (RitualPolicy.Debit(source.Select(ItemId).ToArray(), source.Select((ItemData i) => i.m_stack).ToArray(), costs) == null) { Tell("You do not have the complete offering in your inventory."); yield break; } if (!SpawnPoint(out var _)) { Tell("Clear dry ground beside the shrine before offering."); yield break; } requesting = true; WolfAltar wolfAltar = this; WolfAltar wolfAltar2 = this; bool flag = false; wolfAltar2.granted = false; wolfAltar.answered = flag; request = Guid.NewGuid().ToString("N"); expectedOwner = view.GetZDO().GetOwner(); double started = Time.realtimeSinceStartupAsDouble; try { if (view.IsOwner()) { Reserve(ZNet.GetUID(), request, tier); } else { view.InvokeRPC("WS_Reserve", new object[2] { request, tier }); } while (Object.op_Implicit((Object)(object)view) && view.IsValid() && !answered && Time.realtimeSinceStartupAsDouble - started < 5.0) { yield return null; } if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !answered || !granted) { Tell("The shrine is busy or did not answer. Nothing consumed."); yield break; } while (Object.op_Implicit((Object)(object)view) && view.IsValid() && (!view.IsOwner() || view.GetZDO().GetString("ws_lease", "") != request) && Time.realtimeSinceStartupAsDouble - started < 5.0) { yield return null; } if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !view.IsOwner() || !Access(player) || !OwnLease() || Plugin.Recipes[tier].Value != reviewedRecipe) { Tell("The offering changed or the reservation expired. Nothing consumed."); } else { Commit(player, tier, reviewedRecipe, costs); } } finally { WolfAltar wolfAltar3 = this; if (Object.op_Implicit((Object)(object)wolfAltar3.view) && wolfAltar3.view.IsValid() && wolfAltar3.view.IsOwner() && wolfAltar3.view.GetZDO().GetString("ws_lease", "") == wolfAltar3.request) { wolfAltar3.view.GetZDO().Set("ws_lease", ""); wolfAltar3.view.GetZDO().Set("ws_expiry", 0L); } wolfAltar3.requesting = false; } } private bool OwnLease() { if (view.IsOwner() && view.GetZDO().GetString("ws_lease", "") == request && view.GetZDO().GetLong("ws_holder", 0L) == ZNet.GetUID()) { return TimeAt(view.GetZDO(), "ws_expiry") - Now > 1.0; } return false; } private void Commit(Player player, int tier, string recipe, Dictionary<string, int> costs) { ZDO zDO = view.GetZDO(); if (!OwnLease() || zDO.GetInt("ws_lease_tier", 0) != tier || zDO.GetString("ws_pending", "").Length > 0 || TimeAt(zDO, "ws_next") > Now || !SpawnPoint(out var _)) { Tell("Shrine conditions changed. Nothing consumed."); return; } Inventory inventory = ((Humanoid)player).GetInventory(); ItemData[] array = inventory.GetAllItems().ToArray(); int[] array2 = RitualPolicy.Debit(array.Select(ItemId).ToArray(), array.Select((ItemData i) => i.m_stack).ToArray(), costs); if (array2 == null) { Tell("Your offering is incomplete. Nothing consumed."); return; } int[] array3 = array.Select((ItemData i) => i.m_stack).ToArray(); try { for (int num = 0; num < array.Length; num++) { if (array2[num] > 0 && !inventory.RemoveItem(array[num], array2[num])) { throw new InvalidOperationException("Offering debit failed."); } } zDO.Set("ws_star", tier); zDO.Set("ws_bonus", Plugin.HealthBonus.Value); zDO.Set("ws_paid", recipe); SetTime(zDO, "ws_due", Now + (double)Plugin.RitualSeconds.Value); zDO.Set("ws_pending", request); Tell($"The pack answers: a tamed {tier}-star cub is coming."); } catch (Exception arg) { zDO.Set("ws_pending", ""); List<ItemData> allItems = inventory.GetAllItems(); allItems.Clear(); for (int num2 = 0; num2 < array.Length; num2++) { array[num2].m_stack = array3[num2]; allItems.Add(array[num2]); } try { InventoryChanged(inventory); } catch (Exception arg2) { Plugin.Log.LogError((object)$"Restored offering inventory callback failed: {arg2}"); } Plugin.Log.LogError((object)$"Offering failed; inventory restored before birth. {arg}"); Tell("Offering failed; check inventory and logs."); } } private void Reserve(long sender, string token, int tier) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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) if (!view.IsOwner() || token == null || !Guid.TryParseExact(token, "N", out var _)) { return; } if (!seen.Add(token)) { Reply(sender, token, success: false); return; } history.Enqueue(token); if (history.Count > 256) { seen.Remove(history.Dequeue()); } Player val = ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => Object.op_Implicit((Object)(object)p) && Object.op_Implicit((Object)(object)((Component)p).GetComponent<ZNetView>()) && ((Component)p).GetComponent<ZNetView>().IsValid() && ((Component)p).GetComponent<ZNetView>().GetZDO().GetOwner() == sender)); ZDO zDO = view.GetZDO(); int num; if (Object.op_Implicit((Object)(object)val)) { bool access = Access(val); bool alive = !((Character)val).IsDead(); Vector3 point = ((Component)val).transform.position - ((Component)this).transform.position; if (RitualPolicy.CanReserve(owner: true, access, alive, ((Vector3)(ref point)).sqrMagnitude, tier, zDO.GetString("ws_pending", "").Length > 0, TimeAt(zDO, "ws_next"), TimeAt(zDO, "ws_expiry"), Now) && ValidRecipe(Plugin.Recipes[tier].Value)) { num = (SpawnPoint(out point) ? 1 : 0); goto IL_013c; } } num = 0; goto IL_013c; IL_013c: bool flag = (byte)num != 0; if (flag) { zDO.Set("ws_lease", token); zDO.Set("ws_holder", sender); zDO.Set("ws_lease_tier", tier); SetTime(zDO, "ws_expiry", Now + 12.0); if (sender != ZNet.GetUID()) { zDO.SetOwner(sender); ZDOMan.instance.ForceSendZDO(sender, zDO.m_uid); } } Reply(sender, token, flag); } private void Reply(long sender, string token, bool success) { if (sender == ZNet.GetUID()) { Response(sender, token, success); return; } view.InvokeRPC(sender, "WS_Granted", new object[2] { token, success }); } private void Response(long sender, string token, bool success) { if (token == request && sender == expectedOwner && !answered) { answered = true; granted = success; } } private void Update() { //IL_0161: 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) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !Object.op_Implicit((Object)(object)ZNet.instance)) { return; } ZDO zDO = view.GetZDO(); bool flag = zDO.GetString("ws_pending", "").Length > 0; Light componentInChildren = ((Component)this).GetComponentInChildren<Light>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.intensity = (flag ? (0.26f + Mathf.Sin(Time.time * 4f) * 0.04f) : 0.12f); } if (!view.IsOwner() || !flag || Now < TimeAt(zDO, "ws_due") || Time.unscaledTime < nextBirthCheck) { return; } nextBirthCheck = Time.unscaledTime + 2f; string token = zDO.GetString("ws_pending", ""); int num = zDO.GetInt("ws_star", 0); if (!RitualPolicy.Tier(num)) { Plugin.Log.LogError((object)"Invalid pending wolf tier; ritual held for inspection."); return; } try { Character val = ((IEnumerable<Character>)Character.GetAllCharacters()).FirstOrDefault((Func<Character, bool>)((Character c) => Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent<ZNetView>()) && ((Component)c).GetComponent<ZNetView>().IsValid() && ((Component)c).GetComponent<ZNetView>().GetZDO().GetString("wolfshrine.birth", "") == token)); if (!Object.op_Implicit((Object)(object)val)) { if (!SpawnPoint(out var point)) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("Wolf_cub"); if (!Object.op_Implicit((Object)(object)prefab)) { throw new InvalidOperationException("Wolf_cub is unavailable."); } GameObject val2 = Object.Instantiate<GameObject>(prefab, point, ((Component)this).transform.rotation); try { val = val2.GetComponent<Character>(); ZNetView component = val2.GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner()) { throw new InvalidOperationException("Spawned cub is not a valid owned Character."); } component.GetZDO().Set("wolfshrine.birth", token); } catch { ZNetScene.instance.Destroy(val2); throw; } } BlessedWolves.Mark(val, zDO.GetFloat("ws_bonus", 3f)); val.SetTamed(true); val.SetLevel(RitualPolicy.Level(num)); val.SetHealth(val.GetMaxHealth()); if (!val.IsTamed()) { throw new InvalidOperationException("Cub taming has not been acknowledged; ritual remains pending."); } Growup component2 = ((Component)val).GetComponent<Growup>(); if (Object.op_Implicit((Object)(object)component2)) { component2.m_inheritTame = true; } SetTime(zDO, "ws_next", Now + (double)Plugin.Cooldown.Value); zDO.Set("ws_pending", ""); Plugin.Log.LogInfo((object)$"Shrine cub born: {num} stars, tamed={val.IsTamed()}, maxHealth={val.GetMaxHealth()}, multiplier={BlessedWolves.Bonus(val)}."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Wolf ritual is pending and will retry without charging again: {arg}"); } } private bool SpawnPoint(out Vector3 point) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: 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_0147: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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_0114: Unknown result type (might be due to invalid IL or missing references) int mask = LayerMask.GetMask(new string[4] { "terrain", "piece", "Default", "static_solid" }); int mask2 = LayerMask.GetMask(new string[6] { "piece", "Default", "static_solid", "character", "character_net", "character_ghost" }); RaycastHit val = default(RaycastHit); for (int i = 0; i < 12; i++) { float num = (float)i * (float)Math.PI / 6f; if (Physics.Raycast(((Component)this).transform.position + new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)) * 2.5f + Vector3.up * 2f, Vector3.down, ref val, 4f, mask, (QueryTriggerInteraction)1) && !(Mathf.Abs(((RaycastHit)(ref val)).point.y - ((Component)this).transform.position.y) > 1.5f) && (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !(((RaycastHit)(ref val)).point.y < ZoneSystem.instance.m_waterLevel + 0.1f))) { point = ((RaycastHit)(ref val)).point + Vector3.up * 0.1f; if (!Physics.CheckCapsule(point + Vector3.up * 0.5f, point + Vector3.up * 0.9f, 0.35f, mask2, (QueryTriggerInteraction)1)) { return true; } } } point = Vector3.zero; return false; } private void RefundDestroyed() { try { RefundOffering(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Destroyed shrine refund was incomplete; preserve the world/player backup and logs. {arg}"); } } private void RefundOffering() { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !view.IsOwner()) { return; } ZDO zDO = view.GetZDO(); string token = zDO.GetString("ws_pending", ""); if (token.Length == 0 || Character.GetAllCharacters().Any((Character c) => Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent<ZNetView>()) && ((Component)c).GetComponent<ZNetView>().IsValid() && ((Component)c).GetComponent<ZNetView>().GetZDO().GetString("wolfshrine.birth", "") == token)) { return; } Dictionary<string, int> dictionary = RitualPolicy.Recipe(zDO.GetString("ws_paid", "")); zDO.Set("ws_pending", ""); if (dictionary == null) { Plugin.Log.LogError((object)"Destroyed shrine has an invalid paid offering record; preserve the backup."); return; } foreach (KeyValuePair<string, int> item in dictionary) { ItemData itemData = ObjectDB.instance.GetItemPrefab(item.Key).GetComponent<ItemDrop>().m_itemData; int num = item.Value; while (num > 0) { int num2 = Math.Min(num, itemData.m_shared.m_maxStackSize); ItemDrop.DropItem(itemData.Clone(), num2, ((Component)this).transform.position + Vector3.up, Quaternion.identity); num -= num2; } } Plugin.Log.LogInfo((object)"Destroyed active shrine dropped its pending offering as ordinary items."); } private static void Tell(string message) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } } } internal static class WolfUnlock { internal const string Key = "wolfshrine.wolf_tamed"; private static readonly Dictionary<ZDOID, bool> observed = new Dictionary<ZDOID, bool>(); private static Player current = null; private static float nextScan; private static readonly Action<Player> KnownRecipes = AccessTools.MethodDelegate<Action<Player>>(AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null), (object)null, true); private static readonly Action<Player> AvailablePieces = AccessTools.MethodDelegate<Action<Player>>(AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null), (object)null, true); internal static bool Has(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return false; } if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { if (player.m_customData.TryGetValue("wolfshrine.wolf_tamed", out var value)) { return value == "1"; } return false; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { return component.GetZDO().GetBool("wolfshrine.wolf_tamed", false); } return false; } internal static bool OrdinaryTame(Character wolf) { if (BlessedWolves.IsWolf(wolf) && wolf.IsTamed()) { return !BlessedWolves.FromShrine(wolf); } return false; } internal static void Credit(Player player) { if (Object.op_Implicit((Object)(object)player) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && !Has(player)) { player.m_customData["wolfshrine.wolf_tamed"] = "1"; Synchronize(player); KnownRecipes(player); AvailablePieces(player); ((Character)player).Message((MessageType)2, "Altar of the Pack unlocked — your bond with wolves is remembered.", 0, (Sprite)null, false); Plugin.Log.LogInfo((object)"Wolf-taming progression unlocked for the local character."); } } private static void Synchronize(Player player) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.IsOwner() && component.GetZDO().GetBool("wolfshrine.wolf_tamed", false) != Has(player)) { component.GetZDO().Set("wolfshrine.wolf_tamed", Has(player)); } } internal static void Update() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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_00f8: 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) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)current != (Object)(object)localPlayer) { current = localPlayer; observed.Clear(); nextScan = 0f; } if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance)) { return; } Synchronize(localPlayer); if (Has(localPlayer) || ((Character)localPlayer).IsDead() || Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 0.5f; HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); foreach (Character allCharacter in Character.GetAllCharacters()) { if (!BlessedWolves.IsWolf(allCharacter) || BlessedWolves.FromShrine(allCharacter)) { continue; } Vector3 val2 = ((Component)allCharacter).transform.position - ((Component)localPlayer).transform.position; if (((Vector3)(ref val2)).sqrMagnitude > 900f) { continue; } ZNetView component = ((Component)allCharacter).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { ZDOID uid = component.GetZDO().m_uid; hashSet.Add(uid); bool flag = allCharacter.IsTamed(); if (observed.TryGetValue(uid, out var value) && !value && flag && (Object)(object)Player.GetClosestPlayer(((Component)allCharacter).transform.position, 30f) == (Object)(object)localPlayer) { Credit(localPlayer); } observed[uid] = flag; } } foreach (ZDOID item in new List<ZDOID>(observed.Keys)) { if (!hashSet.Contains(item)) { observed.Remove(item); } } } internal static bool IsShrine(Piece piece) { if (Object.op_Implicit((Object)(object)piece)) { return Utils.GetPrefabName(((Component)piece).gameObject) == "WolfShrine_AltarOfThePack"; } return false; } } [HarmonyPatch(typeof(Tameable), "Interact")] internal static class RecognizeExistingWolf { private static void Postfix(Tameable __instance, Humanoid user, bool hold, bool __result) { if (!hold && __result && (Object)(object)user == (Object)(object)Player.m_localPlayer && WolfUnlock.OrdinaryTame(((Component)__instance).GetComponent<Character>())) { WolfUnlock.Credit(Player.m_localPlayer); } } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] internal static class WolfShrineBuildKnowledge { private static void Postfix(Player __instance, Piece piece, ref bool __result) { if (WolfUnlock.IsShrine(piece) && !WolfUnlock.Has(__instance)) { __result = false; } } } [HarmonyPatch] internal static class WolfShrinePlacementGate { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(Player), "TryPlacePiece", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Player), "PlacePiece", (Type[])null, (Type[])null); } private static bool Prefix(Player __instance, Piece __0) { if (!WolfUnlock.IsShrine(__0) || WolfUnlock.Has(__instance)) { return true; } if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { ((Character)__instance).Message((MessageType)2, "Tame a wolf, or pet an existing ordinary tame wolf, to unlock this shrine.", 0, (Sprite)null, false); } return false; } } }