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 LoquatScrapPack v0.3.4
BepInEx\plugins\LoquatScrapPack\LoquatScrapPack.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("LethalLib")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LoquatScrapPack")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.4.0")] [assembly: AssemblyInformationalVersion("0.3.4")] [assembly: AssemblyProduct("LoquatScrapPack")] [assembly: AssemblyTitle("LoquatScrapPack")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LoquatScrapPack { internal sealed class BalbalGlowMarker : MonoBehaviour { private MeshRenderer targetRenderer; private Material runtimeMaterial; private Light pointLight; private int pulseVersion; private Color baseColor = Color.white; private static readonly Color GlowColor = new Color(0.23f, 0.64f, 1f, 1f); private void Awake() { try { InitializeVisuals(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Balbal glow setup was disabled: " + ex.GetBaseException().Message)); ((Behaviour)this).enabled = false; } } private void InitializeVisuals() { //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_008c: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)this).transform.Find("FGS_Visual"); targetRenderer = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshRenderer>() : ((Component)this).GetComponentInChildren<MeshRenderer>(true)); if ((Object)(object)targetRenderer != (Object)null && (Object)(object)((Renderer)targetRenderer).sharedMaterial != (Object)null) { runtimeMaterial = new Material(((Renderer)targetRenderer).sharedMaterial) { name = ((Object)((Renderer)targetRenderer).sharedMaterial).name + "_BalbalRuntime" }; ((Renderer)targetRenderer).sharedMaterial = runtimeMaterial; if (runtimeMaterial.HasProperty("_BaseColor")) { baseColor = runtimeMaterial.GetColor("_BaseColor"); } else if (runtimeMaterial.HasProperty("_Color")) { baseColor = runtimeMaterial.GetColor("_Color"); } } Transform val2 = ((Component)this).transform.Find("FGS_BalbalGlowLight"); if ((Object)(object)val2 != (Object)null) { GameObject gameObject = ((Component)val2).gameObject; pointLight = gameObject.GetComponent<Light>() ?? gameObject.AddComponent<Light>(); } else { GameObject gameObject = new GameObject("FGS_BalbalGlowLight"); gameObject.transform.SetParent(((Component)this).transform, false); gameObject.transform.localPosition = new Vector3(0f, 0.5f, 0f); pointLight = gameObject.AddComponent<Light>(); } pointLight.type = (LightType)2; pointLight.color = GlowColor; pointLight.range = 1.8f; pointLight.intensity = 8f; pointLight.shadows = (LightShadows)0; ((Behaviour)pointLight).enabled = false; SetGlow(enabled: false); } internal void Pulse(float seconds) { pulseVersion++; int version = pulseVersion; ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).StartCoroutine(PulseRoutine(Mathf.Max(0.25f, seconds), version)); } internal void PulseForCurrentPlayback(float fallbackSeconds = 4f) { pulseVersion++; int version = pulseVersion; ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).StartCoroutine(PulseForCurrentPlaybackRoutine(Mathf.Max(0.25f, fallbackSeconds), version)); } private IEnumerator PulseRoutine(float seconds, int version) { SetGlow(enabled: true); yield return (object)new WaitForSeconds(seconds); if (version == pulseVersion) { SetGlow(enabled: false); } } private IEnumerator PulseForCurrentPlaybackRoutine(float fallbackSeconds, int version) { SetGlow(enabled: true); AudioSource active = null; float startWait = 0f; while ((Object)(object)active == (Object)null && startWait < 0.4f) { AudioSource[] componentsInChildren = ((Component)this).GetComponentsInChildren<AudioSource>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && componentsInChildren[i].isPlaying) { active = componentsInChildren[i]; break; } } if ((Object)(object)active != (Object)null) { break; } startWait += Time.deltaTime; yield return null; } if ((Object)(object)active == (Object)null) { yield return (object)new WaitForSeconds(fallbackSeconds); } else { float safety = 0f; while ((Object)(object)active != (Object)null && active.isPlaying && safety < 60f) { safety += Time.deltaTime; yield return null; } } if (version == pulseVersion) { SetGlow(enabled: false); } } private void SetGlow(bool enabled) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_0093: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pointLight != (Object)null) { ((Behaviour)pointLight).enabled = enabled; } if ((Object)(object)runtimeMaterial == (Object)null) { return; } Color val = (enabled ? Color.Lerp(baseColor, GlowColor, 0.1f) : baseColor); if (runtimeMaterial.HasProperty("_BaseColor")) { runtimeMaterial.SetColor("_BaseColor", val); } if (runtimeMaterial.HasProperty("_Color")) { runtimeMaterial.SetColor("_Color", val); } Color val2 = (enabled ? (GlowColor * 0.65f) : Color.black); if (runtimeMaterial.HasProperty("_EmissiveColor")) { runtimeMaterial.SetColor("_EmissiveColor", val2); } if (runtimeMaterial.HasProperty("_EmissiveColorLDR")) { runtimeMaterial.SetColor("_EmissiveColorLDR", val2); } if (runtimeMaterial.HasProperty("_EmissionColor")) { runtimeMaterial.SetColor("_EmissionColor", val2); if (enabled) { runtimeMaterial.EnableKeyword("_EMISSION"); } else { runtimeMaterial.DisableKeyword("_EMISSION"); } } } } internal static class BlumpkinSpawner { private static int lastAttemptFrame = int.MinValue; private static readonly BindingFlags InspectFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal static void TrySpawn() { //IL_00c0: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ItemFactory.BlumpkinItem == (Object)null || (Object)(object)ItemFactory.BlumpkinItem.spawnPrefab == (Object)null || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsListening || !NetworkManager.Singleton.IsServer || Time.frameCount == lastAttemptFrame) { return; } lastAttemptFrame = Time.frameCount; List<Transform> list = FindPumpkinRoots(); if (list.Count == 0 && !CurrentLevelSupportsPumpkins()) { return; } float num = Mathf.Clamp(Plugin.ModConfig.BlumpkinChancePercent.Value, 0f, 100f); if (Random.Range(0f, 100f) >= num) { return; } Vector3 position; if (list.Count > 0) { position = PositionNear(list[Random.Range(0, list.Count)].position, 0.8f, 1.4f); } else if (!TryGetOutsideSpawnPosition(out position)) { Plugin.Log.LogWarning((object)"Blumpkin moon was pumpkin-eligible, but no safe outside spawn point was found."); return; } SnapToGround(ref position); GameObject val = Object.Instantiate<GameObject>(ItemFactory.BlumpkinItem.spawnPrefab, position, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); GrabbableObject component = val.GetComponent<GrabbableObject>(); if ((Object)(object)component != (Object)null) { int val2 = Mathf.RoundToInt((float)ItemFactory.BlumpkinItem.minValue * 0.4f); int val3 = Mathf.RoundToInt((float)ItemFactory.BlumpkinItem.maxValue * 0.4f); int num2 = Random.Range(Math.Min(val2, val3), Math.Max(val2, val3) + 1); try { MethodInfo methodInfo = AccessTools.Method(typeof(GrabbableObject), "SetScrapValue", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(component, new object[1] { num2 }); } else { ReflectionUtil.SetMember(component, "scrapValue", num2); } } catch { ReflectionUtil.SetMember(component, "scrapValue", num2); } } NetworkObject component2 = val.GetComponent<NetworkObject>(); if ((Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val); Plugin.Log.LogError((object)"Blumpkin prefab has no NetworkObject."); return; } try { if (!component2.IsSpawned) { component2.Spawn(false); } Plugin.Log.LogInfo((object)"A Blumpkin spawned outside on a pumpkin-eligible moon."); } catch (Exception ex) { Object.Destroy((Object)(object)val); Plugin.Log.LogDebug((object)("Blumpkin network spawn was skipped: " + ex.GetBaseException().Message)); } } private static Vector3 PositionNear(Vector3 origin, float minRadius, float maxRadius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Random.insideUnitCircle; if (((Vector2)(ref val)).sqrMagnitude < 0.01f) { val = Vector2.right; } ((Vector2)(ref val)).Normalize(); Vector2 val2 = val * Random.Range(minRadius, maxRadius); return origin + new Vector3(val2.x, 1.5f, val2.y); } private static void SnapToGround(ref Vector3 spawnPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (Physics.Raycast(spawnPosition + Vector3.up * 3f, Vector3.down, ref val, 12f, -1, (QueryTriggerInteraction)1)) { spawnPosition = ((RaycastHit)(ref val)).point + Vector3.up * 0.15f; } } private static bool TryGetOutsideSpawnPosition(out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; try { GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode"); if (array != null && array.Length != 0) { GameObject val = array[Random.Range(0, array.Length)]; position = PositionNear(val.transform.position, 0.4f, 2f); return true; } } catch { } return false; } private static bool CurrentLevelSupportsPumpkins() { if ((Object)(object)StartOfRound.Instance == (Object)null) { return false; } object member = ReflectionUtil.GetMember(StartOfRound.Instance, "currentLevel"); if (member == null) { return false; } string[] array = new string[4] { "spawnableMapObjects", "spawnableOutsideObjects", "spawnableOutsideObjectsWithRarity", "randomMapObjects" }; foreach (string name in array) { if (ContainsPumpkinReference(ReflectionUtil.GetMember(member, name), 3, new HashSet<object>())) { return true; } } return false; } private static bool ContainsPumpkinReference(object value, int depth, HashSet<object> visited) { if (value == null || depth < 0) { return false; } if (value is string text) { return text.IndexOf("pumpkin", StringComparison.OrdinalIgnoreCase) >= 0; } Object val = (Object)((value is Object) ? value : null); if (val != (Object)null && !string.IsNullOrEmpty(val.name) && val.name.IndexOf("pumpkin", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } Type type = value.GetType(); if (type.IsPrimitive || type.IsEnum || type == typeof(decimal)) { return false; } if (!type.IsValueType) { if (visited.Contains(value)) { return false; } visited.Add(value); } if (value is IEnumerable enumerable && !(value is string)) { int num = 0; foreach (object item in enumerable) { if (ContainsPumpkinReference(item, depth - 1, visited)) { return true; } if (++num >= 256) { break; } } return false; } if (depth == 0) { return false; } FieldInfo[] fields = type.GetFields(InspectFlags); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.Name.IndexOf("pumpkin", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } object value2; try { value2 = fieldInfo.GetValue(value); } catch { continue; } if (ContainsPumpkinReference(value2, depth - 1, visited)) { return true; } } PropertyInfo[] properties = type.GetProperties(InspectFlags); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0) { if (propertyInfo.Name.IndexOf("pumpkin", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } object value3; try { value3 = propertyInfo.GetValue(value, null); } catch { continue; } if (ContainsPumpkinReference(value3, depth - 1, visited)) { return true; } } } return false; } private static List<Transform> FindPumpkinRoots() { return Object.FindObjectsOfType<Transform>(true).Where(delegate(Transform transform) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform != (Object)null) { Scene scene = ((Component)transform).gameObject.scene; if (((Scene)(ref scene)).IsValid() && ((Component)transform).gameObject.activeInHierarchy && ((Object)transform).name.IndexOf("pumpkin", StringComparison.OrdinalIgnoreCase) >= 0) { return !AncestorNameContainsPumpkin(transform.parent); } } return false; }).ToList(); } private static bool AncestorNameContainsPumpkin(Transform transform) { while ((Object)(object)transform != (Object)null) { if (((Object)transform).name.IndexOf("pumpkin", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } transform = transform.parent; } return false; } } internal static class ItemFactory { private static bool buildAttempted; private static int successfulBuilds; internal static Item BlumpkinItem { get; private set; } internal static Item ShumovkaItem { get; private set; } internal static Item BaconEggCheeseItem { get; private set; } internal static Item BalbalItem { get; private set; } internal static Item TvorogItem { get; private set; } internal static Item ZubrowkaItem { get; private set; } internal static Item MoutaiItem { get; private set; } internal static Item KyivCakeItem { get; private set; } internal static Item BimbkaItem { get; private set; } internal static Item HasbullahItem { get; private set; } internal static Item DoshirakItem { get; private set; } internal static Item MenorahItem { get; private set; } internal static void BuildAll() { if (buildAttempted) { return; } buildAttempted = true; ModConfig cfg = Plugin.ModConfig; Item shovel = FindTemplateWithComponent<Shovel>(new string[1] { "Shovel" }); if ((Object)(object)shovel == (Object)null) { shovel = FindAnyTemplateWithComponent<Shovel>(); } Item clownHorn = FindTemplateWithComponent<NoisemakerProp>(new string[6] { "Clown horn", "Clownhorn", "Clown Horn", "ClownHorn", "Airhorn", "Air horn" }); if ((Object)(object)clownHorn == (Object)null) { clownHorn = FindAnyTemplateWithComponent<NoisemakerProp>(); } Item neutralScrap = FindPlainScrapTemplate("Mug", "Toy cube", "ToyCube", "Metal sheet", "MetalSheet", "Large axle", "Big bolt", "BigBolt", "Cog1"); Item hive = FindTemplate("Hive", "RedLocustHive", "Red locust hive") ?? FindTemplateContains("hive"); Item bottleSoundDonor = FindTemplate("Flask", "BottleBin", "PerfumeBottle", "Molotov", "Molotov cocktail") ?? FindTemplateContains("bottle"); Item cakeSoundDonor = FindTemplate("Gift", "Gift box", "Gift Box", "GiftBox") ?? FindTemplateContains("gift"); LogTemplate("Shovel", shovel); LogTemplate("Noisemaker", clownHorn); LogTemplate("Neutral scrap", neutralScrap); LogTemplate("Hive sound donor", hive); float maxSeconds = Mathf.Max(0f, cfg.MusicExcerptSeconds.Value); AudioClip val = CreateSilentClip(); AudioClip baconClip = TryLoadWav("BaconEggCheese.wav", maxSeconds) ?? val; AudioClip tvorogClip = TryLoadWav("Tvorog.wav", maxSeconds) ?? val; AudioClip menorahSilence = TryLoadWav("MenorahSilence.wav") ?? val; AudioClip[] balbalClips = ((IEnumerable<AudioClip>)(object)new AudioClip[4] { TryLoadWav("Balbal_01.wav"), TryLoadWav("Balbal_02.wav"), TryLoadWav("Balbal_03.wav"), TryLoadWav("Balbal_04.wav") }).Where((AudioClip clip) => (Object)(object)clip != (Object)null).ToArray(); if (balbalClips.Length == 0) { balbalClips = (AudioClip[])(object)new AudioClip[1] { val }; } ShumovkaItem = TryBuildScrap("Shumovka", cfg.ShumovkaRarity.Value, delegate { RequireTemplate(shovel, "a shovel-class donor"); Item obj = CreateItem(shovel, "Shumovka", "Shumovka", cfg.ShumovkaScale.Value, 19f, 95, 185, twoHanded: false, null, preserveTemplateHandling: true); Mark(obj, LoquatItemKind.Shumovka); return obj; }); BaconEggCheeseItem = TryBuildScrap("Bacon Egg and Cheese Sandwich", cfg.BaconEggCheeseRarity.Value, delegate { RequireTemplate(clownHorn, "a noisemaker donor"); Item val2 = CreateItem(clownHorn, "Bacon Egg and Cheese Sandwich", "BaconEggCheese", cfg.BaconEggCheeseScale.Value, 2f, 80, 160, twoHanded: false); ConfigureNoisemaker(val2, (AudioClip[])(object)new AudioClip[1] { baconClip }); ReflectionUtil.SetMember(val2, "useCooldown", Math.Max(0.5f, baconClip.length)); Mark(val2, LoquatItemKind.BaconEggCheese); return val2; }); BalbalItem = TryBuildScrap("Balbal", cfg.BalbalRarity.Value, delegate { RequireTemplate(clownHorn, "a noisemaker donor"); Item obj = CreateItem(clownHorn, "Balbal", "Balbal", cfg.BalbalScale.Value, 78f, 150, 290, twoHanded: true); ConfigureNoisemaker(obj, balbalClips); ReflectionUtil.SetMember(obj, "useCooldown", 1f); AddComponentIfMissing<BalbalGlowMarker>(obj.spawnPrefab); Mark(obj, LoquatItemKind.Balbal); return obj; }); TvorogItem = TryBuildScrap("Tvorog", cfg.TvorogRarity.Value, delegate { RequireTemplate(clownHorn, "a noisemaker donor"); Item val2 = CreateItem(clownHorn, "Tvorog", "Tvorog", cfg.TvorogScale.Value, 4f, 90, 175, twoHanded: false); ConfigureNoisemaker(val2, (AudioClip[])(object)new AudioClip[1] { tvorogClip }); ReflectionUtil.SetMember(val2, "useCooldown", Math.Max(0.5f, tvorogClip.length)); Mark(val2, LoquatItemKind.Tvorog); return val2; }); ZubrowkaItem = TryBuildScrap("Żubrówka", cfg.ZubrowkaRarity.Value, delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Żubrówka", "Zubrowka", cfg.ZubrowkaScale.Value, 3f, 90, 170, twoHanded: false); CopyVanillaHandlingSounds(bottleSoundDonor ?? neutralScrap, val2); Mark(val2, LoquatItemKind.Zubrowka); return val2; }); MoutaiItem = TryBuildScrap("Kweichow Moutai", cfg.MoutaiRarity.Value, delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Kweichow Moutai", "Moutai", cfg.MoutaiScale.Value, 4f, 180, 330, twoHanded: false); CopyVanillaHandlingSounds(bottleSoundDonor ?? neutralScrap, val2); Mark(val2, LoquatItemKind.Moutai); return val2; }); KyivCakeItem = TryBuildScrap("Roshen Київський", cfg.KyivCakeRarity.Value, delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Roshen Київський", "KyivCake", cfg.KyivCakeScale.Value, 10f, 105, 200, twoHanded: false, "Roshen Київський"); CopyVanillaHandlingSounds(cakeSoundDonor ?? neutralScrap, val2); Mark(val2, LoquatItemKind.KyivCake); return val2; }); BimbkaItem = TryBuildScrap("Bimbka", cfg.BimbkaRarity.Value, delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Bimbka", "Bimbka", cfg.BimbkaScale.Value, 72f, 175, 325, twoHanded: true); CopyVanillaHandlingSounds(neutralScrap, val2); Mark(val2, LoquatItemKind.Bimbka); return val2; }); HasbullahItem = TryBuildScrap("Hasbullah", cfg.HasbullahRarity.Value, delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Hasbullah", "Hasbullah", cfg.HasbullahScale.Value, 46f, 210, 390, twoHanded: true); CopyVanillaHandlingSounds(neutralScrap, val2); Mark(val2, LoquatItemKind.Hasbullah); return val2; }); DoshirakItem = TryBuildScrap("Doshirak", cfg.DoshirakRarity.Value, delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Doshirak", "Doshirak", cfg.DoshirakScale.Value, 2f, 80, 155, twoHanded: false); CopyVanillaHandlingSounds(neutralScrap, val2); Mark(val2, LoquatItemKind.Doshirak); return val2; }); MenorahItem = TryBuildScrap("Menorah", cfg.MenorahRarity.Value, delegate { RequireTemplate(clownHorn, "a noisemaker donor"); Item val2 = CreateItem(clownHorn, "Menorah", "Menorah", cfg.MenorahScale.Value, 18f, 145, 275, twoHanded: false); ConfigureNoisemaker(val2, (AudioClip[])(object)new AudioClip[1] { menorahSilence }); ReflectionUtil.SetMember(val2, "useCooldown", 0.75f); NoisemakerProp component = val2.spawnPrefab.GetComponent<NoisemakerProp>(); if ((Object)(object)component != (Object)null) { ReflectionUtil.SetMember(component, "noiseRange", 0f); ReflectionUtil.SetMember(component, "maxLoudness", 0f); ReflectionUtil.SetMember(component, "minLoudness", 0f); AddComponentIfMissing<MenorahLightMarker>(val2.spawnPrefab); } CopyVanillaHandlingSounds(neutralScrap, val2); Mark(val2, LoquatItemKind.Menorah); return val2; }); BlumpkinItem = TryBuildItem("Blumpkin", delegate { RequireTemplate(neutralScrap, "a plain scrap donor"); Item val2 = CreateItem(neutralScrap, "Blumpkin", "Blumpkin", cfg.BlumpkinScale.Value, 12f, 230, 420, twoHanded: false, "Blumpkin (blue pumpkin)"); CopyVanillaHandlingSounds(hive ?? neutralScrap, val2); Mark(val2, LoquatItemKind.Blumpkin); return val2; }); ConfigureUprightRest(BaconEggCheeseItem, 0f); ConfigureUprightRest(BalbalItem, 0f); ConfigureUprightRest(TvorogItem, 0f); ConfigureUprightRest(ZubrowkaItem, 0f); ConfigureUprightRest(MoutaiItem, 0f); ConfigureUprightRest(KyivCakeItem, 0f); ConfigureUprightRest(BlumpkinItem, 0f); ConfigureUprightRest(BimbkaItem, 0f); ConfigureUprightRest(HasbullahItem, 0f); ConfigureUprightRest(DoshirakItem, 0f); ConfigureUprightRest(MenorahItem, 0f); float value = cfg.HeldFacingYawDegrees.Value; ConfigureHeldFacing(BaconEggCheeseItem, value); ConfigureHeldFacing(BalbalItem, value); ConfigureHeldFacing(TvorogItem, value); ConfigureHeldFacing(ZubrowkaItem, value); ConfigureHeldFacing(MoutaiItem, value); ConfigureHeldFacing(KyivCakeItem, value); ConfigureHeldFacing(BlumpkinItem, value); ConfigureHeldFacing(BimbkaItem, value); ConfigureHeldFacing(HasbullahItem, value); ConfigureHeldFacing(DoshirakItem, value); ConfigureHeldFacing(MenorahItem, value); Plugin.Log.LogInfo((object)$"Loquat initialization finished: {successfulBuilds}/12 items registered. Failed items were skipped without interrupting game startup."); } private static Item TryBuildScrap(string label, int rarity, Func<Item> factory) { Item val = TryCreate(label, factory); if ((Object)(object)val == (Object)null) { return null; } try { Items.RegisterScrap(val, Mathf.Max(0, rarity), (LevelTypes)(-1)); successfulBuilds++; return val; } catch (Exception ex) { Plugin.Log.LogError((object)(label + " was created but could not be added to the scrap table; it will be unavailable this session. " + ex.GetBaseException().Message)); return null; } } private static Item TryBuildItem(string label, Func<Item> factory) { Item val = TryCreate(label, factory); if ((Object)(object)val == (Object)null) { return null; } try { Items.RegisterItem(val); successfulBuilds++; return val; } catch (Exception ex) { Plugin.Log.LogError((object)(label + " was created but could not be registered; it will be unavailable this session. " + ex.GetBaseException().Message)); return null; } } private static Item TryCreate(string label, Func<Item> factory) { try { Item val = factory(); if ((Object)(object)val == (Object)null || !HasUsableSpawnPrefab(val)) { throw new InvalidOperationException("item creation returned an unusable prefab"); } return val; } catch (Exception ex) { Plugin.Log.LogError((object)("Skipping Loquat item '" + label + "': " + ex.GetBaseException().Message)); return null; } } private static void RequireTemplate(Item item, string description) { if (!HasUsableSpawnPrefab(item)) { throw new InvalidOperationException("Could not find " + description + " with a usable network prefab."); } } private static T AddComponentIfMissing<T>(GameObject target) where T : Component { if ((Object)(object)target == (Object)null) { return default(T); } return target.GetComponent<T>() ?? target.AddComponent<T>(); } private static void Mark(Item item, LoquatItemKind kind) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item.spawnPrefab == (Object)null)) { LoquatItemMarker loquatItemMarker = AddComponentIfMissing<LoquatItemMarker>(item.spawnPrefab); if ((Object)(object)loquatItemMarker != (Object)null) { loquatItemMarker.Kind = kind; } } } private static AudioClip TryLoadWav(string fileName, float maxSeconds = 0f) { try { return RuntimeAssets.LoadWav(fileName, maxSeconds); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Audio asset '" + fileName + "' could not be loaded; a silent fallback will be used. " + ex.GetBaseException().Message)); return null; } } private static AudioClip CreateSilentClip() { AudioClip obj = AudioClip.Create("LoquatSilentFallback", 2205, 1, 44100, false); obj.SetData(new float[2205], 0); return obj; } private static bool HasUsableSpawnPrefab(Item item) { if ((Object)(object)item == (Object)null || (Object)(object)item.spawnPrefab == (Object)null) { return false; } if ((Object)(object)item.spawnPrefab.GetComponent<GrabbableObject>() != (Object)null) { return (Object)(object)item.spawnPrefab.GetComponent<NetworkObject>() != (Object)null; } return false; } private static bool IsLoquatGenerated(Item item) { if ((Object)(object)item == (Object)null) { return false; } if (string.IsNullOrEmpty(((Object)item).name) || !((Object)item).name.StartsWith("FGS_", StringComparison.Ordinal)) { if ((Object)(object)item.spawnPrefab != (Object)null && !string.IsNullOrEmpty(((Object)item.spawnPrefab).name)) { return ((Object)item.spawnPrefab).name.StartsWith("FGS_", StringComparison.Ordinal); } return false; } return true; } private static Item FindTemplate(params string[] names) { Item[] source = Resources.FindObjectsOfTypeAll<Item>(); foreach (string name in names) { Item val = ((IEnumerable<Item>)(from item in source.Where(HasUsableSpawnPrefab) where !IsLoquatGenerated(item) orderby MatchScore(item, name) descending select item)).FirstOrDefault((Func<Item, bool>)((Item item) => MatchScore(item, name) > 0)); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Item FindTemplateWithComponent<T>(params string[] names) where T : Component { Item[] source = Resources.FindObjectsOfTypeAll<Item>(); foreach (string name in names) { Item val = ((IEnumerable<Item>)(from item in source.Where(HasUsableSpawnPrefab) where !IsLoquatGenerated(item) where (Object)(object)item.spawnPrefab.GetComponent<T>() != (Object)null orderby MatchScore(item, name) descending select item)).FirstOrDefault((Func<Item, bool>)((Item item) => MatchScore(item, name) > 0)); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Item FindAnyTemplateWithComponent<T>() where T : Component { return (from item in Resources.FindObjectsOfTypeAll<Item>().Where(HasUsableSpawnPrefab) where !IsLoquatGenerated(item) where (Object)(object)item.spawnPrefab.GetComponent<T>() != (Object)null select item).OrderBy<Item, string>((Item item) => ((Object)item).name ?? string.Empty, StringComparer.OrdinalIgnoreCase).FirstOrDefault(); } private static Item FindPlainScrapTemplate(params string[] preferredNames) { Item val = FindTemplate(preferredNames); if ((Object)(object)val != (Object)null && IsPlainGrabbable(val)) { return val; } foreach (string name in preferredNames) { Item val2 = ((IEnumerable<Item>)(from item in (from item in Resources.FindObjectsOfTypeAll<Item>().Where(HasUsableSpawnPrefab) where !IsLoquatGenerated(item) select item).Where(IsPlainGrabbable) orderby MatchScore(item, name) descending select item)).FirstOrDefault((Func<Item, bool>)((Item item) => MatchScore(item, name) > 0)); if ((Object)(object)val2 != (Object)null) { return val2; } } return (from item in (from item in Resources.FindObjectsOfTypeAll<Item>().Where(HasUsableSpawnPrefab) where !IsLoquatGenerated(item) select item).Where(IsPlainGrabbable) where item.isScrap select item).OrderBy<Item, string>((Item item) => ((Object)item).name ?? string.Empty, StringComparer.OrdinalIgnoreCase).FirstOrDefault(); } private static bool IsPlainGrabbable(Item item) { if (!HasUsableSpawnPrefab(item)) { return false; } GrabbableObject component = item.spawnPrefab.GetComponent<GrabbableObject>(); if ((Object)(object)component != (Object)null) { return ((object)component).GetType() == typeof(GrabbableObject); } return false; } private static Item FindTemplateContains(string fragment) { string normalized = NormalizeName(fragment); return (from item in Resources.FindObjectsOfTypeAll<Item>().Where(HasUsableSpawnPrefab) where !IsLoquatGenerated(item) where ContainsNormalized(item.itemName, normalized) || ContainsNormalized(((Object)item).name, normalized) || ContainsNormalized(((Object)(object)item.spawnPrefab == (Object)null) ? null : ((Object)item.spawnPrefab).name, normalized) select item).OrderBy<Item, string>((Item item) => ((Object)item).name ?? string.Empty, StringComparer.OrdinalIgnoreCase).FirstOrDefault(); } private static int MatchScore(Item item, string requested) { string text = NormalizeName(requested); if (text.Length == 0 || (Object)(object)item == (Object)null) { return 0; } string text2 = NormalizeName(item.itemName); string text3 = NormalizeName(((Object)item).name); string text4 = NormalizeName(((Object)(object)item.spawnPrefab == (Object)null) ? null : ((Object)item.spawnPrefab).name); if (text3 == text) { return 50; } if (text4 == text) { return 45; } if (text2 == text) { return 30; } if (text3.EndsWith(text, StringComparison.Ordinal)) { return 20; } if (text4.EndsWith(text, StringComparison.Ordinal)) { return 15; } return 0; } private static bool ContainsNormalized(string value, string normalizedFragment) { return NormalizeName(value).IndexOf(normalizedFragment, StringComparison.Ordinal) >= 0; } private static string NormalizeName(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(value.Length); foreach (char c in value) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(char.ToLowerInvariant(c)); } } return stringBuilder.ToString(); } private static void LogTemplate(string label, Item item) { if ((Object)(object)item == (Object)null) { Plugin.Log.LogWarning((object)(label + " donor: not found; dependent Loquat items will be skipped.")); return; } string text = (((Object)(object)item.spawnPrefab == (Object)null) ? "<null>" : ((Object)item.spawnPrefab).name); string text2 = (((Object)(object)item.spawnPrefab == (Object)null) ? "<none>" : (((object)item.spawnPrefab.GetComponent<GrabbableObject>())?.GetType().Name ?? "<no GrabbableObject>")); Plugin.Log.LogInfo((object)(label + " donor: Item '" + item.itemName + "' / asset '" + ((Object)item).name + "' / prefab '" + text + "' / component '" + text2 + "'.")); } private static Item CreateItem(Item template, string displayName, string assetName, float visualScale, float pounds, int minInternalValue, int maxInternalValue, bool twoHanded, string scanHeader = null, bool preserveTemplateHandling = false) { RequireTemplate(template, "a donor for " + displayName); Item val = null; GameObject val2 = null; try { val = Object.Instantiate<Item>(template); ((Object)val).name = "FGS_" + assetName + "_Item"; val.itemName = displayName; val.isScrap = true; val.minValue = Math.Min(minInternalValue, maxInternalValue); val.maxValue = Math.Max(minInternalValue, maxInternalValue); val.weight = Mathf.Clamp(1f + pounds / 105f, 1f, 3.75f); if (!preserveTemplateHandling) { val.twoHanded = twoHanded; ReflectionUtil.SetMember(val, "twoHandedAnimation", twoHanded); if (twoHanded) { ReflectionUtil.SetMember(val, "grabAnim", "HoldLung"); } } val2 = PrefabUtils.ClonePrefab(template.spawnPrefab, "FGS_" + assetName + "_Prefab"); if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("Could not clone the donor prefab for " + displayName + "."); } NetworkObject component = val2.GetComponent<NetworkObject>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("Donor prefab for " + displayName + " has no root NetworkObject."); } GrabbableObject component2 = val2.GetComponent<GrabbableObject>(); if ((Object)(object)component2 == (Object)null) { throw new InvalidOperationException("Donor prefab for " + displayName + " has no root GrabbableObject."); } val.spawnPrefab = val2; component2.itemProperties = val; ReplaceVisual(val2, component2, assetName, Mathf.Max(0.01f, visualScale), scanHeader ?? displayName); AssignDeterministicNetworkHash(component, ((Object)val2).name); NetworkPrefabs.RegisterNetworkPrefab(val2); return val; } catch { if ((Object)(object)val2 != (Object)null) { Object.DestroyImmediate((Object)(object)val2); } if ((Object)(object)val != (Object)null) { Object.DestroyImmediate((Object)(object)val); } throw; } } private static void AssignDeterministicNetworkHash(NetworkObject networkObject, string prefabName) { if ((Object)(object)networkObject == (Object)null) { throw new ArgumentNullException("networkObject"); } string name = typeof(Plugin).Assembly.GetName().Name; uint num; using (MD5 mD = MD5.Create()) { num = BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes(name + prefabName)), 0); } if (!ReflectionUtil.SetMember(networkObject, "GlobalObjectIdHash", num) && !ReflectionUtil.SetMember(networkObject, "m_GlobalObjectIdHash", num) && !ReflectionUtil.SetMember(networkObject, "<GlobalObjectIdHash>k__BackingField", num)) { throw new InvalidOperationException("Could not assign a deterministic NetworkObject hash to " + prefabName + "."); } } private static void ReplaceVisual(GameObject prefab, GrabbableObject grabbable, string assetName, float visualScale, string scanHeader) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_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_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0169: 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: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_036e: 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_0231: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029f: 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_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: 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_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05d6: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_05f4: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); Renderer val = (Renderer)(object)grabbable.mainObjectRenderer; if ((Object)(object)val == (Object)null) { val = ((IEnumerable<Renderer>)componentsInChildren).FirstOrDefault((Func<Renderer, bool>)((Renderer renderer) => renderer is MeshRenderer && (Object)(object)((Component)renderer).GetComponent<MeshFilter>() != (Object)null)); } if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("Could not find a mesh anchor renderer for " + assetName + "."); } GameObject gameObject = ((Component)val).gameObject; int layer = gameObject.layer; MeshRenderer val2 = (MeshRenderer)(object)((val is MeshRenderer) ? val : null); MeshFilter val3 = gameObject.GetComponent<MeshFilter>(); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { val.enabled = false; val3 = gameObject.GetComponent<MeshFilter>() ?? gameObject.AddComponent<MeshFilter>(); val2 = gameObject.GetComponent<MeshRenderer>() ?? gameObject.AddComponent<MeshRenderer>(); } Quaternion localRotation = gameObject.transform.localRotation; Vector3 localPosition = gameObject.transform.localPosition; gameObject.layer = layer; for (int num = gameObject.transform.childCount - 1; num >= 0; num--) { Transform child = gameObject.transform.GetChild(num); if ((Object)(object)child != (Object)null && (((Object)child).name.StartsWith("FGS_Part_", StringComparison.Ordinal) || ((Object)child).name == "FGS_ShumovkaVisual")) { Object.DestroyImmediate((Object)(object)((Component)child).gameObject); } } MeshFilter val4 = val3; MeshRenderer val5 = val2; if (assetName == "Shumovka") { GameObject val6 = new GameObject("FGS_ShumovkaVisual") { layer = layer }; val6.transform.SetParent(gameObject.transform, false); val6.transform.localPosition = Vector3.zero; val6.transform.localRotation = Quaternion.identity; val6.transform.localScale = Vector3.one; val4 = val6.AddComponent<MeshFilter>(); val5 = val6.AddComponent<MeshRenderer>(); } Bounds val7 = default(Bounds); bool flag = false; if (RuntimeAssets.HasVisualParts(assetName)) { List<RuntimeAssets.VisualPart> list = RuntimeAssets.LoadVisualParts(assetName); if (list.Count == 0) { throw new InvalidOperationException("Visual-parts manifest for " + assetName + " contained no parts."); } RuntimeAssets.VisualPart visualPart = list[0]; val4.sharedMesh = visualPart.Mesh; ((Renderer)val5).sharedMaterial = visualPart.Material; ((Renderer)val5).enabled = true; val7 = visualPart.Mesh.bounds; flag = true; for (int num2 = 1; num2 < list.Count; num2++) { RuntimeAssets.VisualPart visualPart2 = list[num2]; GameObject val8 = new GameObject("FGS_Part_" + visualPart2.Name) { layer = layer }; val8.transform.SetParent(((Component)val5).transform, false); val8.transform.localPosition = Vector3.zero; val8.transform.localRotation = Quaternion.identity; val8.transform.localScale = Vector3.one; val8.AddComponent<MeshFilter>().sharedMesh = visualPart2.Mesh; ((Renderer)val8.AddComponent<MeshRenderer>()).sharedMaterial = visualPart2.Material; Bounds bounds = visualPart2.Mesh.bounds; ((Bounds)(ref val7)).Encapsulate(((Bounds)(ref bounds)).min); bounds = visualPart2.Mesh.bounds; ((Bounds)(ref val7)).Encapsulate(((Bounds)(ref bounds)).max); } } else { Mesh val9 = (val4.sharedMesh = RuntimeAssets.LoadMesh(assetName)); ((Renderer)val5).sharedMaterial = RuntimeAssets.CreateMaterial(assetName); ((Renderer)val5).enabled = true; val7 = val9.bounds; flag = true; } float targetLongestDimensionMetres = GetTargetLongestDimensionMetres(assetName); float num3 = Mathf.Max(((Bounds)(ref val7)).size.x, Mathf.Max(((Bounds)(ref val7)).size.y, ((Bounds)(ref val7)).size.z)); float num4 = ((num3 > 0.0001f) ? (targetLongestDimensionMetres / num3 * Mathf.Max(0.05f, visualScale)) : 1f); Transform parent = gameObject.transform.parent; float num5 = 1f; if ((Object)(object)parent != (Object)null) { Vector3 lossyScale = parent.lossyScale; num5 = Mathf.Max(0.0001f, Mathf.Max(Mathf.Abs(lossyScale.x), Mathf.Max(Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z)))); } float num6 = num4 / num5; gameObject.transform.localScale = Vector3.one * num6; float value = Plugin.ModConfig.ModelRotationZDegrees.Value; Quaternion modelSpaceCorrection = GetModelSpaceCorrection(assetName, value); gameObject.transform.localPosition = localPosition; if (assetName == "Shumovka") { gameObject.transform.localRotation = localRotation * modelSpaceCorrection; Vector3 val11 = default(Vector3); ((Vector3)(ref val11))..ctor(0f, 0.16f, 0.31f); Vector3 val12 = modelSpaceCorrection * val11; gameObject.transform.localPosition = localPosition - localRotation * val12 * num6; } else { gameObject.transform.localRotation = modelSpaceCorrection; } Renderer[] array = componentsInChildren; foreach (Renderer val13 in array) { if ((Object)(object)val13 == (Object)null || (Object)(object)val13 == (Object)(object)val5) { continue; } val13.enabled = false; MeshRenderer val14 = (MeshRenderer)(object)((val13 is MeshRenderer) ? val13 : null); if ((Object)(object)val14 != (Object)null) { MeshFilter component = ((Component)val14).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null) { component.sharedMesh = null; } ((Renderer)val14).sharedMaterial = null; } else { SkinnedMeshRenderer val15 = (SkinnedMeshRenderer)(object)((val13 is SkinnedMeshRenderer) ? val13 : null); if ((Object)(object)val15 != (Object)null) { val15.sharedMesh = null; ((Renderer)val15).sharedMaterial = null; } } } grabbable.mainObjectRenderer = val5; Collider[] componentsInChildren2 = prefab.GetComponentsInChildren<Collider>(true); foreach (Collider val16 in componentsInChildren2) { if ((Object)(object)val16 != (Object)null && !val16.isTrigger) { val16.enabled = false; } } BoxCollider val17 = gameObject.GetComponent<BoxCollider>() ?? gameObject.AddComponent<BoxCollider>(); ((Collider)val17).enabled = true; ((Collider)val17).isTrigger = false; if (flag) { val17.center = ((Bounds)(ref val7)).center; val17.size = Vector3.Max(((Bounds)(ref val7)).size * 0.9f, new Vector3(0.08f, 0.08f, 0.08f)); } UpdateScanNode(prefab, scanHeader); Plugin.Log.LogInfo((object)$"Bound {assetName} to '{((Object)gameObject).name}': target longest dimension {targetLongestDimensionMetres:0.00} m, size multiplier {visualScale:0.##}, extra local Z rotation {value:0.#} deg. Donor anchor preserved; per-model correction applied where required."); } private static Quaternion GetModelSpaceCorrection(string assetName, float extraZDegrees) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //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_003c: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) Quaternion val = Quaternion.identity; if (assetName == "Shumovka") { Quaternion val2 = Quaternion.AngleAxis(-124.5f, Vector3.right); val = Quaternion.AngleAxis(Plugin.ModConfig.ShumovkaRollDegrees.Value, Vector3.up) * val2; } if (Mathf.Abs(extraZDegrees) > 0.001f) { val *= Quaternion.Euler(0f, 0f, extraZDegrees); } return val; } private static void ConfigureHeldFacing(Item item, float yawDegrees) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)item == (Object)null) && !(Mathf.Abs(yawDegrees) < 0.001f)) { object member = ReflectionUtil.GetMember(item, "rotationOffset"); Vector3 val = (Vector3)((member is Vector3) ? ((Vector3)member) : Vector3.zero); val.y = NormalizeDegrees(val.y + yawDegrees); ReflectionUtil.SetMember(item, "rotationOffset", val); Plugin.Log.LogInfo((object)$"Held-facing correction for {item.itemName}: +{yawDegrees:0.#}° yaw -> rotationOffset {val}."); } } private static float NormalizeDegrees(float degrees) { degrees %= 360f; if (degrees > 180f) { degrees -= 360f; } if (degrees < -180f) { degrees += 360f; } return degrees; } private static void ConfigureUprightRest(Item item, float zDegrees) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)item == (Object)null)) { ReflectionUtil.SetMember(item, "restingRotation", (object)new Vector3(0f, 0f, zDegrees)); ReflectionUtil.SetMember(item, "verticalOffset", 0f); } } private static float GetTargetLongestDimensionMetres(string assetName) { return assetName switch { "Shumovka" => 1.1f, "BaconEggCheese" => 0.2f, "Balbal" => 1.2f, "Blumpkin" => 0.42f, "Tvorog" => 0.24f, "Zubrowka" => 0.33f, "Moutai" => 0.25f, "KyivCake" => 0.3f, "Bimbka" => 0.85f, "Hasbullah" => 0.75f, "Doshirak" => 0.24f, "Menorah" => 0.55f, _ => 0.35f, }; } private static void UpdateScanNode(GameObject prefab, string headerText) { MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !(((object)val).GetType().Name != "ScanNodeProperties")) { ReflectionUtil.SetMember(val, "headerText", headerText); break; } } } private static void ConfigureNoisemaker(Item item, AudioClip[] clips) { NoisemakerProp component = item.spawnPrefab.GetComponent<NoisemakerProp>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException(item.itemName + " was cloned from a noisemaker but has no NoisemakerProp."); } ReflectionUtil.SetMember(component, "noiseSFX", clips); ReflectionUtil.SetMember(component, "noiseSFXFar", clips); ReflectionUtil.SetMember(component, "minPitch", 1f); ReflectionUtil.SetMember(component, "maxPitch", 1f); ReflectionUtil.SetMember(item, "syncUseFunction", true); } private static void CopyVanillaHandlingSounds(Item source, Item destination) { if ((Object)(object)source == (Object)null || (Object)(object)destination == (Object)null) { return; } string[] array = new string[4] { "grabSFX", "dropSFX", "pocketSFX", "throwSFX" }; foreach (string name in array) { object member = ReflectionUtil.GetMember(source, name); if (member != null) { ReflectionUtil.SetMember(destination, name, member); } } } } internal enum LoquatItemKind { Unknown, Shumovka, BaconEggCheese, Balbal, Tvorog, Zubrowka, Moutai, KyivCake, Bimbka, Hasbullah, Doshirak, Menorah, Blumpkin } internal sealed class LoquatItemMarker : MonoBehaviour { [SerializeField] private LoquatItemKind kind; internal LoquatItemKind Kind { get { return kind; } set { kind = value; } } } internal sealed class MenorahLightMarker : MonoBehaviour { private GameObject flamesRoot; private Light warmLight; private float lastToggleTime = -10f; private bool isLit = true; internal bool IsLit => isLit; private void Start() { try { BuildFlames(); SetLit(value: true); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Menorah visual setup was disabled: " + ex.GetBaseException().Message)); ((Behaviour)this).enabled = false; } } private void BuildFlames() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_01cf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)flamesRoot != (Object)null) { return; } GrabbableObject component = ((Component)this).GetComponent<GrabbableObject>(); Renderer val = (Renderer)(((Object)(object)component != (Object)null) ? ((object)component.mainObjectRenderer) : ((object)((Component)this).GetComponentInChildren<Renderer>(true))); Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform : ((Component)this).transform); MeshFilter component2 = ((Component)val2).GetComponent<MeshFilter>(); Bounds val3 = (Bounds)(((Object)(object)component2 != (Object)null && (Object)(object)component2.sharedMesh != (Object)null) ? component2.sharedMesh.bounds : new Bounds(new Vector3(0f, 0.5f, 0f), new Vector3(0.8f, 1f, 0.35f))); flamesRoot = new GameObject("FGS_MenorahFlames"); flamesRoot.transform.SetParent(val2, false); Material sharedMaterial = CreateFlameMaterial(); float num = ((Bounds)(ref val3)).extents.x * 0.86f; float num2 = ((Bounds)(ref val3)).max.y - ((Bounds)(ref val3)).size.y * 0.05f; float num3 = ((Bounds)(ref val3)).max.y + ((Bounds)(ref val3)).size.y * 0.005f; float z = ((Bounds)(ref val3)).center.z; for (int i = 0; i < 9; i++) { float num4 = (float)(i - 4) / 4f * num; float num5 = ((i == 4) ? num3 : num2); GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "FGS_MenorahFlame_" + i; obj.transform.SetParent(flamesRoot.transform, false); obj.transform.localPosition = new Vector3(num4, num5, z); float num6 = ((Bounds)(ref val3)).size.y * 0.019f; obj.transform.localScale = new Vector3(num6 * 0.75f, num6 * 1.55f, num6 * 0.75f); Collider component3 = obj.GetComponent<Collider>(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } Renderer component4 = obj.GetComponent<Renderer>(); if ((Object)(object)component4 != (Object)null) { component4.sharedMaterial = sharedMaterial; } } GameObject val4 = new GameObject("FGS_MenorahWarmLight"); val4.transform.SetParent(val2, false); val4.transform.localPosition = new Vector3(0f, ((Bounds)(ref val3)).max.y, z); warmLight = val4.AddComponent<Light>(); warmLight.type = (LightType)2; warmLight.color = new Color(1f, 0.48f, 0.16f, 1f); warmLight.range = 2.4f; warmLight.intensity = 6f; warmLight.shadows = (LightShadows)0; } private static Material CreateFlameMaterial() { //IL_0033: 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_0044: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00aa: 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) Shader val = Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = "FGS_MenorahFlameMaterial" }; Color val3 = default(Color); ((Color)(ref val3))..ctor(1f, 0.34f, 0.06f, 1f); if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", val3); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", val3); } if (val2.HasProperty("_EmissiveColor")) { val2.SetColor("_EmissiveColor", val3 * 4f); } if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", val3 * 4f); val2.EnableKeyword("_EMISSION"); } return val2; } internal void ToggleFromActivation() { if (!(Time.unscaledTime - lastToggleTime < 0.65f)) { lastToggleTime = Time.unscaledTime; SetLit(!isLit); } } private void SetLit(bool value) { isLit = value; if ((Object)(object)flamesRoot != (Object)null) { flamesRoot.SetActive(value); } if ((Object)(object)warmLight != (Object)null) { ((Behaviour)warmLight).enabled = value; } } internal bool CanRelightNearFire() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) if (isLit) { return true; } Vector3 position = ((Component)this).transform.position; MenorahLightMarker[] array = Object.FindObjectsOfType<MenorahLightMarker>(); foreach (MenorahLightMarker menorahLightMarker in array) { if ((Object)(object)menorahLightMarker != (Object)null && (Object)(object)menorahLightMarker != (Object)(object)this && menorahLightMarker.IsLit && Vector3.Distance(position, ((Component)menorahLightMarker).transform.position) <= 2.25f) { return true; } } Collider[] array2 = Physics.OverlapSphere(position, 2.25f, -1, (QueryTriggerInteraction)2); foreach (Collider val in array2) { if (!((Object)(object)val == (Object)null) && LooksLikeFire(((Component)val).transform)) { return true; } } ParticleSystem[] array3 = Object.FindObjectsOfType<ParticleSystem>(); foreach (ParticleSystem val2 in array3) { if ((Object)(object)val2 != (Object)null && val2.isPlaying && Vector3.Distance(position, ((Component)val2).transform.position) <= 2.25f && LooksLikeFire(((Component)val2).transform)) { return true; } } MonoBehaviour[] array4 = Object.FindObjectsOfType<MonoBehaviour>(); foreach (MonoBehaviour val3 in array4) { if (!((Object)(object)val3 == (Object)null) && !(Vector3.Distance(position, ((Component)val3).transform.position) > 2.25f)) { string text = ((object)val3).GetType().Name.ToLowerInvariant(); if (!text.Contains("fireexit") && (text.Contains("flame") || text.Contains("campfire") || text.Contains("bonfire") || text.Contains("fireplace") || text.Contains("lighter") || text.Contains("torch"))) { return true; } } } return false; } private static bool LooksLikeFire(Transform transform) { Transform val = transform; while ((Object)(object)val != (Object)null) { string text = ((Object)val).name.ToLowerInvariant(); if (!text.Contains("fireexit") && !text.Contains("fire exit") && (text.Contains("flame") || text.Contains("campfire") || text.Contains("bonfire") || text.Contains("fireplace") || text.Contains("lighter") || text.Contains("torch") || text.Contains("candle"))) { return true; } val = val.parent; } return false; } internal void PlayFailedRelightFeedback() { Plugin.Log.LogInfo((object)"Menorah is extinguished; bring it near an active flame/fire source to relight it."); } } internal sealed class ModConfig { internal readonly ConfigEntry<int> ShumovkaRarity; internal readonly ConfigEntry<int> BaconEggCheeseRarity; internal readonly ConfigEntry<int> BalbalRarity; internal readonly ConfigEntry<int> TvorogRarity; internal readonly ConfigEntry<int> ZubrowkaRarity; internal readonly ConfigEntry<int> MoutaiRarity; internal readonly ConfigEntry<int> KyivCakeRarity; internal readonly ConfigEntry<int> BimbkaRarity; internal readonly ConfigEntry<int> HasbullahRarity; internal readonly ConfigEntry<int> DoshirakRarity; internal readonly ConfigEntry<int> MenorahRarity; internal readonly ConfigEntry<float> BlumpkinChancePercent; internal readonly ConfigEntry<float> MusicExcerptSeconds; internal readonly ConfigEntry<string> BaconEggCheeseEmoteName; internal readonly ConfigEntry<string> TvorogEmoteName; internal readonly ConfigEntry<float> ShumovkaScale; internal readonly ConfigEntry<float> BaconEggCheeseScale; internal readonly ConfigEntry<float> BalbalScale; internal readonly ConfigEntry<float> BlumpkinScale; internal readonly ConfigEntry<float> TvorogScale; internal readonly ConfigEntry<float> ZubrowkaScale; internal readonly ConfigEntry<float> MoutaiScale; internal readonly ConfigEntry<float> KyivCakeScale; internal readonly ConfigEntry<float> BimbkaScale; internal readonly ConfigEntry<float> HasbullahScale; internal readonly ConfigEntry<float> DoshirakScale; internal readonly ConfigEntry<float> MenorahScale; internal readonly ConfigEntry<float> ShumovkaRollDegrees; internal readonly ConfigEntry<float> ModelRotationZDegrees; internal readonly ConfigEntry<float> HeldFacingYawDegrees; internal ModConfig(ConfigFile config) { ShumovkaRarity = config.Bind<int>("Spawn", "ShumovkaRarity", 6, "Relative scrap rarity on all moons. Intentionally rare by default."); BaconEggCheeseRarity = config.Bind<int>("Spawn", "BaconEggCheeseRarity", 5, "Relative scrap rarity on all moons. Intentionally rare by default."); BalbalRarity = config.Bind<int>("Spawn", "BalbalRarity", 3, "Relative scrap rarity on all moons. Very rare by default."); TvorogRarity = config.Bind<int>("Spawn", "TvorogRarity", 5, "Relative scrap rarity on all moons. Intentionally rare by default."); ZubrowkaRarity = config.Bind<int>("Spawn", "ZubrowkaRarity", 5, "Relative scrap rarity on all moons. Intentionally rare by default."); MoutaiRarity = config.Bind<int>("Spawn", "MoutaiRarity", 2, "Relative scrap rarity on all moons. Very rare premium bottle."); KyivCakeRarity = config.Bind<int>("Spawn", "KyivCakeRarity", 4, "Relative scrap rarity on all moons. Intentionally rare by default."); BimbkaRarity = config.Bind<int>("Spawn", "BimbkaRarity", 3, "Relative scrap rarity on all moons. Heavy and very rare, like Balbal."); HasbullahRarity = config.Bind<int>("Spawn", "HasbullahRarity", 1, "Extremely rare two-handed inert scrap."); DoshirakRarity = config.Bind<int>("Spawn", "DoshirakRarity", 4, "Rare inert instant-noodle tray scrap."); MenorahRarity = config.Bind<int>("Spawn", "MenorahRarity", 3, "Very rare interactive menorah scrap."); BlumpkinChancePercent = config.Bind<float>("Spawn", "BlumpkinChancePercent", 1.5f, "Chance per landing to spawn one Blumpkin on pumpkin-eligible moons. It is deliberately rarer than normal custom scrap."); MusicExcerptSeconds = config.Bind<float>("Audio", "MusicExcerptSeconds", 0f, "Length of Bacon Egg and Cheese / Tvorog audio used by the item. Set to 0 to play the full source clip (default)."); BaconEggCheeseEmoteName = config.Bind<string>("TooManyEmotes v2", "BaconEggCheeseEmoteName", "feelin'_jaunty", "One exact TooManyEmotes emote identifier requested by Bacon Egg and Cheese. Upbeat/pop-dance default; no random fallback."); TvorogEmoteName = config.Bind<string>("TooManyEmotes v2", "TvorogEmoteName", "smug_dance", "One exact TooManyEmotes emote identifier requested by Tvorog. Smooth/swaying default; no random fallback."); ShumovkaScale = config.Bind<float>("Visuals v5", "ShumovkaSizeMultiplier", 1.2f, "Multiplier on the enlarged shovel-class Shumovka target size."); BaconEggCheeseScale = config.Bind<float>("Visuals v5", "BaconEggCheeseSizeMultiplier", 1.2f, "Multiplier on the ~0.20 m sandwich target size."); BalbalScale = config.Bind<float>("Visuals v5", "BalbalSizeMultiplier", 1.2f, "Multiplier on the ~1.20 m Balbal target size. 1.20 default makes the statue ~1.44 m tall/longest-axis target."); BlumpkinScale = config.Bind<float>("Visuals v5", "BlumpkinSizeMultiplier", 1.2f, "Multiplier on the ~0.42 m pumpkin target size."); TvorogScale = config.Bind<float>("Visuals v5", "TvorogSizeMultiplier", 1.2f, "Multiplier on the ~0.24 m bowl target size."); ZubrowkaScale = config.Bind<float>("Visuals v5", "ZubrowkaSizeMultiplier", 1.2f, "Multiplier on the ~0.33 m bottle target size."); MoutaiScale = config.Bind<float>("Visuals v5", "MoutaiSizeMultiplier", 1.2f, "Multiplier on the ~0.25 m bottle target size."); KyivCakeScale = config.Bind<float>("Visuals v5", "KyivCakeSizeMultiplier", 1.2f, "Multiplier on the ~0.30 m cake-box target diameter."); BimbkaScale = config.Bind<float>("Visuals v5", "BimbkaSizeMultiplier", 1.2f, "Multiplier on the ~0.85 m heavy Bimbka target size."); HasbullahScale = config.Bind<float>("Visuals v5", "HasbullahSizeMultiplier", 1.2f, "Multiplier on the ~0.75 m Hasbullah target size."); DoshirakScale = config.Bind<float>("Visuals v5", "DoshirakSizeMultiplier", 1.2f, "Multiplier on the ~0.24 m Doshirak tray target size."); MenorahScale = config.Bind<float>("Visuals v5", "MenorahSizeMultiplier", 1.2f, "Multiplier on the ~0.55 m menorah target size."); ShumovkaRollDegrees = config.Bind<float>("Visuals v5", "ShumovkaRollDegrees", 45f, "Roll around Shumovka's long handle axis. 45 degrees makes the spoon/skimmer bowl perpendicular to the player's torso."); ModelRotationZDegrees = config.Bind<float>("Visuals v5", "ModelRotationZDegrees", 0f, "Advanced global model-space Z correction. Leave at 0; floor orientation is now fixed using each Item's resting rotation instead."); HeldFacingYawDegrees = config.Bind<float>("Held Poses v1", "HeldFacingYawDegrees", 180f, "Held-only yaw correction for Loquat Scrap Pack items except Shumovka. 180 makes front-facing props face the player while carried; dropped orientation is unaffected."); } } internal static class ModPatches { internal static bool BeforeNoisemakerActivate(NoisemakerProp __instance, object[] __args) { try { if (GetKind((Component)(object)__instance) != LoquatItemKind.Menorah) { return true; } if (IsReleaseCallback(__args)) { return true; } MenorahLightMarker component = ((Component)__instance).GetComponent<MenorahLightMarker>(); if ((Object)(object)component == (Object)null) { return true; } if (component.IsLit || component.CanRelightNearFire()) { return true; } component.PlayFailedRelightFeedback(); return false; } catch (Exception ex) { Plugin.Log.LogDebug((object)("Menorah activation compatibility fallback: " + ex.GetBaseException().Message)); return true; } } internal static void BeforeGameNetworkManagerStart() { try { ItemFactory.BuildAll(); } catch (Exception ex) { Plugin.Log.LogError((object)("Loquat item initialization stopped unexpectedly. The game will continue without any remaining Loquat items. " + ex)); } } internal static void AfterNoisemakerActivate(NoisemakerProp __instance, object[] __args) { try { LoquatItemKind kind = GetKind((Component)(object)__instance); switch (kind) { case LoquatItemKind.Unknown: return; case LoquatItemKind.Balbal: PulseBalbal(__instance); break; } if (kind == LoquatItemKind.Menorah) { MenorahLightMarker component = ((Component)__instance).GetComponent<MenorahLightMarker>(); if ((Object)(object)component != (Object)null) { component.ToggleFromActivation(); } } if (!IsReleaseCallback(__args) && (kind == LoquatItemKind.BaconEggCheese || kind == LoquatItemKind.Tvorog)) { object member = ReflectionUtil.GetMember(__instance, "playerHeldBy"); if ((Object)(object)StartOfRound.Instance != (Object)null && member == StartOfRound.Instance.localPlayerController) { TooManyEmotesCompat.TryDance((kind == LoquatItemKind.BaconEggCheese) ? Plugin.ModConfig.BaconEggCheeseEmoteName.Value : Plugin.ModConfig.TvorogEmoteName.Value); } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Loquat noisemaker post-activation hook was skipped: " + ex.GetBaseException().Message)); } } internal static void AfterNoisemakerNetworkPlayback(NoisemakerProp __instance) { try { switch (GetKind((Component)(object)__instance)) { case LoquatItemKind.Balbal: PulseBalbal(__instance); break; case LoquatItemKind.Menorah: { MenorahLightMarker component = ((Component)__instance).GetComponent<MenorahLightMarker>(); if ((Object)(object)component != (Object)null) { component.ToggleFromActivation(); } break; } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Remote Loquat noisemaker feedback was skipped: " + ex.GetBaseException().Message)); } } internal static void AfterShovelActivate(Shovel __instance) { try { if (IsShumovka(__instance)) { object member = ReflectionUtil.GetMember(ReflectionUtil.GetMember(__instance, "playerHeldBy"), "playerBodyAnimator"); Animator val = (Animator)((member is Animator) ? member : null); if (!((Object)(object)val == (Object)null) && ReflectionUtil.GetMember(__instance, "reelingUp") is int num && num != 0) { val.ResetTrigger("shovelHit"); val.SetBool("reelingUp", true); } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Shumovka reel animation compatibility fallback: " + ex.GetBaseException().Message)); } } internal static void AfterShovelSwing(Shovel __instance) { try { if (IsShumovka(__instance)) { object member = ReflectionUtil.GetMember(ReflectionUtil.GetMember(__instance, "playerHeldBy"), "playerBodyAnimator"); Animator val = (Animator)((member is Animator) ? member : null); if ((Object)(object)val != (Object)null) { val.SetBool("reelingUp", false); val.ResetTrigger("shovelHit"); val.SetTrigger("shovelHit"); } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Shumovka swing animation compatibility fallback: " + ex.GetBaseException().Message)); } } private static bool IsShumovka(Shovel shovel) { return GetKind((Component)(object)shovel) == LoquatItemKind.Shumovka; } private static LoquatItemKind GetKind(Component component) { if ((Object)(object)component == (Object)null) { return LoquatItemKind.Unknown; } LoquatItemMarker component2 = component.GetComponent<LoquatItemMarker>(); if (!((Object)(object)component2 == (Object)null)) { return component2.Kind; } return LoquatItemKind.Unknown; } private static bool IsReleaseCallback(object[] args) { if (args != null && args.Length != 0 && args[0] is bool && !(bool)args[0]) { return true; } if (args != null && args.Length > 1 && args[1] is bool && !(bool)args[1]) { return true; } return false; } private static void PulseBalbal(NoisemakerProp prop) { BalbalGlowMarker balbalGlowMarker = (((Object)(object)prop == (Object)null) ? null : ((Component)prop).GetComponent<BalbalGlowMarker>()); if ((Object)(object)balbalGlowMarker != (Object)null) { balbalGlowMarker.PulseForCurrentPlayback(); } } internal static void AfterSpawnMapObjects() { try { BlumpkinSpawner.TrySpawn(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Blumpkin spawn attempt skipped: " + ex.GetBaseException().Message)); } } } [BepInPlugin("sosigelite.loquatscrappack", "Loquat Scrap Pack", "0.3.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "sosigelite.loquatscrappack"; public const string PluginName = "Loquat Scrap Pack"; public const string PluginVersion = "0.3.4"; private Harmony harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ModConfig ModConfig { get; private set; } internal static string ModDirectory { get; private set; } private void Awake() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); ModConfig = new ModConfig(((BaseUnityPlugin)this).Config); harmony = new Harmony("sosigelite.loquatscrappack"); if (!TryPatch(typeof(GameNetworkManager), "Start", typeof(ModPatches), "BeforeGameNetworkManagerStart", prefix: true, 800, quietIfMissing: false)) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not install the Loquat item-registration hook. The pack will stay disabled for this session, but the game will continue normally."); } TryPatch(typeof(NoisemakerProp), "ItemActivate", typeof(ModPatches), "BeforeNoisemakerActivate", prefix: true, 200, quietIfMissing: false); TryPatch(typeof(NoisemakerProp), "ItemActivate", typeof(ModPatches), "AfterNoisemakerActivate", prefix: false, 200, quietIfMissing: false); TryPatchNoisemakerPlaybackRpc(); TryPatch(typeof(Shovel), "ItemActivate", typeof(ModPatches), "AfterShovelActivate", prefix: false, 200, quietIfMissing: true); TryPatch(typeof(Shovel), "SwingShovel", typeof(ModPatches), "AfterShovelSwing", prefix: false, 200, quietIfMissing: true); TryPatch(typeof(RoundManager), "SpawnMapObjects", typeof(ModPatches), "AfterSpawnMapObjects", prefix: false, 200, quietIfMissing: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loquat Scrap Pack 0.3.4 loaded."); } private bool TryPatch(Type targetType, string methodName, Type patchType, string patchName, bool prefix, int priority, bool quietIfMissing) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null); if (methodInfo == null) { if (!quietIfMissing) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Patch target " + targetType.Name + "." + methodName + " was not found. Related Loquat functionality will be disabled.")); } else { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Optional patch target " + targetType.Name + "." + methodName + " was not found.")); } return false; } MethodInfo methodInfo2 = AccessTools.Method(patchType, patchName, (Type[])null, (Type[])null); if (methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Internal patch method " + patchType.Name + "." + patchName + " was not found.")); return false; } HarmonyMethod val = new HarmonyMethod(methodInfo2) { priority = priority }; harmony.Patch((MethodBase)methodInfo, prefix ? val : null, prefix ? null : val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not patch " + targetType.Name + "." + methodName + "; related Loquat functionality will be disabled. " + ex.GetBaseException().Message)); return false; } } private void TryPatchNoisemakerPlaybackRpc() { //IL_00b4: 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_00c5: Expected O, but got Unknown try { MethodInfo methodInfo = (from method in typeof(NoisemakerProp).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where method.Name.IndexOf("ClientRpc", StringComparison.OrdinalIgnoreCase) >= 0 where method.Name.IndexOf("Noise", StringComparison.OrdinalIgnoreCase) >= 0 || method.Name.IndexOf("Sound", StringComparison.OrdinalIgnoreCase) >= 0 orderby string.Equals(method.Name, "PlayNoiseClientRpc", StringComparison.Ordinal) descending select method).FirstOrDefault(); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogDebug((object)"No compatible NoisemakerProp playback ClientRpc was found; remote Loquat noisemaker visual feedback is disabled."); return; } HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(ModPatches), "AfterNoisemakerNetworkPlayback", (Type[])null, (Type[])null)) { priority = 200 }; harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Remote noisemaker feedback attached to " + methodInfo.Name + ".")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Remote noisemaker feedback could not be patched and was disabled: " + ex.GetBaseException().Message)); } } } internal static class ReflectionUtil { private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; internal static bool SetMember(object target, string name, object value) { if (target == null || string.IsNullOrEmpty(name)) { return false; } try { Type type = ((target is Type) ? ((Type)target) : target.GetType()); object obj = ((target is Type) ? null : target); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(obj, value); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(obj, value, null); return true; } } catch { } return false; } internal static object GetMember(object target, string name) { if (target == null || string.IsNullOrEmpty(name)) { return null; } try { Type type = ((target is Type) ? ((Type)target) : target.GetType()); object obj = ((target is Type) ? null : target); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(obj); } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanRead) { return property.GetValue(obj, null); } } catch { } return null; } internal static T GetMember<T>(object target, string name) where T : class { return GetMember(target, name) as T; } } internal static class RuntimeAssets { internal sealed class VisualPart { internal string Name; internal Mesh Mesh; internal Material Material; internal bool Transparent; } private static string AssetRoot => Path.Combine(Plugin.ModDirectory, "AssetsData"); internal static Mesh LoadMesh(string assetName) { return LoadMeshFile(Path.Combine(AssetRoot, "Meshes", assetName + ".meshbin"), "FGS_" + assetName); } private static Mesh LoadMeshFile(string path, string meshName) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown using FileStream input = File.OpenRead(path); using BinaryReader binaryReader = new BinaryReader(input); if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "FGSM") { throw new InvalidDataException("Invalid mesh file: " + path); } uint num = binaryReader.ReadUInt32(); if (num != 1) { throw new InvalidDataException($"Unsupported FGSM mesh version {num}: {path}"); } int num2; int num3; Vector3[] array; Vector3[] array2; Vector2[] array3; int[] array4; checked { num2 = (int)binaryReader.ReadUInt32(); num3 = (int)binaryReader.ReadUInt32(); array = (Vector3[])(object)new Vector3[num2]; array2 = (Vector3[])(object)new Vector3[num2]; array3 = (Vector2[])(object)new Vector2[num2]; array4 = new int[num3]; } for (int i = 0; i < num2; i++) { array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } for (int j = 0; j < num2; j++) { array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } for (int k = 0; k < num2; k++) { array3[k] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); } for (int l = 0; l < num3; l++) { array4[l] = checked((int)binaryReader.ReadUInt32()); } Mesh val = new Mesh { name = meshName, indexFormat = (IndexFormat)(num2 > 65535) }; val.vertices = array; val.normals = array2; val.uv = array3; val.triangles = array4; val.RecalculateBounds(); try { val.RecalculateTangents(); } catch { } return val; } internal static bool HasVisualParts(string assetName) { return File.Exists(Path.Combine(AssetRoot, "Parts", assetName, "parts.tsv")); } internal static List<VisualPart> LoadVisualParts(string assetName) { string path = Path.Combine(AssetRoot, "Parts", assetName); string path2 = Path.Combine(path, "parts.tsv"); if (!File.Exists(path2)) { return new List<VisualPart>(); } List<VisualPart> list = new List<VisualPart>(); string[] array = File.ReadAllLines(path2); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && !text.StartsWith("#")) { string[] array2 = text.Split('|'); if (array2.Length < 6) { throw new InvalidDataException("Invalid visual-part line for " + assetName + ": " + text); } string text2 = array2[0]; string path3 = Path.Combine(path, array2[1]); string texturePath = Path.Combine(path, array2[2]); bool transparent = array2[3] == "1"; if (!float.TryParse(array2[4], NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { result = 0.35f; } bool doubleSided = array2[5] == "1"; list.Add(new VisualPart { Name = text2, Mesh = LoadMeshFile(path3, "FGS_" + assetName + "_" + text2), Material = CreatePartMaterial(assetName, text2, texturePath, transparent, result, doubleSided), Transparent = transparent }); } } return list; } internal static Texture2D LoadTexture(string assetName, string suffix, bool linear) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0068: Expected O, but got Unknown string path = Path.Combine(AssetRoot, "Textures", assetName + "_" + suffix + ".png"); if (!File.Exists(path)) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = "FGS_" + assetName + "_" + suffix, wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; ImageConversion.LoadImage(val, File.ReadAllBytes(path)); return val; } private static Texture2D LoadTextureFile(string path, string textureName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002d: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false) { name = textureName, wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; ImageConversion.LoadImage(val, File.ReadAllBytes(path)); return val; } private static Material CreatePartMaterial(string assetName, string partName, string texturePath, bool transparent, float smoothness, bool doubleSided) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) Shader obj = Shader.Find("HDRP/Lit") ?? Shader.Find("Standard"); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("Could not find HDRP/Lit or Standard shader."); } Material val = new Material(obj); ((Object)val).name = "FGS_" + assetName + "_" + partName + "_Material"; Material val2 = val; Texture2D val3 = LoadTextureFile(texturePath, "FGS_" + assetName + "_" + partName + "_Base"); if (val2.HasProperty("_BaseColorMap")) { val2.SetTexture("_BaseColorMap", (Texture)(object)val3); } if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)val3); } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", Color.white); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Color.white); } if (val2.HasProperty("_Smoothness")) { val2.SetFloat("_Smoothness", smoothness); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", smoothness); } if (doubleSided) { val2.doubleSidedGI = true; if (val2.HasProperty("_DoubleSidedEnable")) { val2.SetFloat("_DoubleSidedEnable", 1f); } if (val2.HasProperty("_CullMode")) { val2.SetFloat("_CullMode", 0f); } if (val2.HasProperty("_Cull")) { val2.SetFloat("_Cull", 0f); } val2.EnableKeyword("_DOUBLESIDED_ON"); } if (transparent) { ConfigureTransparentMaterial(val2); } return val2; } private static void ConfigureTransparentMaterial(Material material) { material.SetOverrideTag("RenderType", "Transparent"); material.renderQueue = 3000; if (material.HasProperty("_SurfaceType")) { material.SetFloat("_SurfaceType", 1f); } if (material.HasProperty("_BlendMode")) { material.SetFloat("_BlendMode", 0f); } if (material.HasProperty("_SrcBlend")) { material.SetFloat("_SrcBlend", 5f); } if (material.HasProperty("_DstBlend")) { material.SetFloat("_DstBlend", 10f); } if (material.HasProperty("_ZWrite")) { material.SetFloat("_ZWrite", 0f); } if (material.HasProperty("_AlphaDstBlend")) { material.SetFloat("_AlphaDstBlend", 10f); } material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); material.EnableKeyword("_BLENDMODE_ALPHA"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); } internal static Material CreateMaterial(string assetName) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) Shader obj = Shader.Find("HDRP/Lit") ?? Shader.Find("Standard"); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("Could not find HDRP/Lit or Standard shader."); } Material val = new Material(obj) { name = "FGS_" + assetName + "_Material" }; Texture2D val2 = LoadTexture(assetName, "Base", linear: false); Texture2D val3 = LoadTexture(assetName, "Normal", linear: true); Texture2D val4 = LoadTexture(assetName, "Mask", linear: true); if ((Object)(object)val2 != (Object)null) { if (val.HasProperty("_BaseColorMap")) { val.SetTexture("_BaseColorMap", (Texture)(object)val2); } if (val.HasProperty("_MainTex")) { val.SetTexture("_MainTex", (Texture)(object)val2); } } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", Color.white); } if (val.HasProperty("_Color")) { val.SetColor("_Color", Color.white); } float num = 0.35f; switch (assetName) { case "Zubrowka": num = 0.72f; break; case "Moutai": num = 0.48f; break; case "KyivCake": num = 0.18f; break; case "Hasbullah": num = 0.3f; break; case "Doshirak": num = 0.22f; break; case "Menorah": num = 0.68f; break; case "Shumovka": num = 0.38f; break; } if (val.HasProperty("_Smoothness")) { val.SetFloat("_Smoothness", num); } if (val.HasProperty("_Glossiness")) { val.SetFloat("_Glossiness", num); } if ((Object)(object)val3 != (Object)null) { if (val.HasProperty("_NormalMap")) { val.SetTexture("_NormalMap", (Texture)(object)val3); val.SetFloat("_NormalScale", 1f); val.EnableKeyword("_NORMALMAP_TANGENT_SPACE"); } if (val.HasProperty("_BumpMap")) { val.SetTexture("_BumpMap", (Texture)(object)val3); val.SetFloat("_BumpScale", 1f); val.EnableKeyword("_NORMALMAP"); } } if ((Object)(object)val4 != (Object)null && val.HasProperty("_MaskMap")) { val.SetTexture("_MaskMap", (Texture)(object)val4); } return val; } internal static AudioClip LoadWav(string fileName, float maxSeconds = 0f) { byte[] array = File.ReadAllBytes(Path.Combine(AssetRoot, "Audio", fileName)); int num = 12; short num2 = 0; short num3 = 0; int num4 = 0; short num5 = 0; int num6 = -1; int num7 = 0; if (Encoding.ASCII.GetString(array, 0, 4) != "RIFF" || Encoding.ASCII.GetString(array, 8, 4) != "WAVE") { throw new InvalidDataException(fileName + " is not a RIFF/WAVE file."); } while (num + 8 <= array.Length) { string text = Encoding.ASCII.GetString(array, num, 4); int num8 = BitConverter.ToInt32(array, num + 4); int num