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 SosalMeads v1.2.2
BepInEx/plugins/FartingMatvey/FartingMatvey.dll
Decompiled 10 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FartingMatvey")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3")] [assembly: AssemblyProduct("FartingMatvey")] [assembly: AssemblyTitle("FartingMatvey")] [assembly: AssemblyVersion("1.0.3.0")] [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 FartingMatvey { internal static class EffectRules { public const float Duration = 100f; public const float SpeedPenalty = 0.3f; public const float MinimumInterval = 8f; public const float MaximumInterval = 15f; public const float AudioTail = 2f; public const float MinimumPitch = 0.9f; public const float MaximumPitch = 1.1f; public const float AudioMargin = 0.25f; public const int ClipCount = 8; public static float ApplySpeed(float baseSpeed, float currentSpeed) { return Math.Max(0f, currentSpeed - baseSpeed * 0.3f); } } internal sealed class FartSchedule { private readonly Random random; private readonly float[] durations; private int previous = -1; internal float NextAt { get; private set; } internal float AudioTail { get; } public FartSchedule(Random random, float[] clipDurations = null) { this.random = random ?? throw new ArgumentNullException("random"); AudioTail = 2f; if (clipDurations != null) { if (clipDurations.Length != 8) { throw new ArgumentException("Expected eight sound durations.", "clipDurations"); } durations = (float[])clipDurations.Clone(); float[] array = durations; foreach (float num in array) { if (float.IsNaN(num) || float.IsInfinity(num) || num <= 0f || num > 15f) { throw new ArgumentException("Invalid sound duration.", "clipDurations"); } AudioTail = Math.Max(AudioTail, num / 0.9f + 0.25f); } } Reset(); } public void Reset() { previous = -1; NextAt = Range(2f, 4f); } public bool TryNext(float elapsed, out int clip, out float pitch) { clip = -1; pitch = 1f; if (float.IsNaN(elapsed) || elapsed < NextAt || elapsed >= 100f - AudioTail) { return false; } int num = random.Next(8 - ((previous >= 0) ? 1 : 0)); if (previous >= 0 && num >= previous) { num++; } previous = (clip = num); pitch = Range(0.9f, 1.1f); float num2 = Range(8f, 15f); if (durations != null) { num2 = Math.Max(num2, durations[clip] / pitch + 0.25f); } NextAt = elapsed + num2; return true; } private float Range(float min, float max) { return min + (float)random.NextDouble() * (max - min); } } internal static class FartSynthesis { public const int SampleRate = 22050; private static readonly double[] Length = new double[8] { 0.38, 0.61, 0.83, 1.15, 1.38, 0.49, 0.96, 0.7 }; private static readonly double[] Frequency = new double[8] { 92.0, 63.0, 120.0, 53.0, 76.0, 148.0, 67.0, 104.0 }; public static float[] Create(int variant) { if (variant < 0 || variant >= 8) { throw new ArgumentOutOfRangeException("variant"); } Random random = new Random(1701 + variant * 997); double num = Length[variant]; float[] array = new float[(int)(22050.0 * num)]; double num2 = 0.0; double num3 = 0.0; double num4 = 0.0; double num5 = 0.0; float num6 = 0f; for (int i = 0; i < array.Length; i++) { double num7 = (double)i / 22050.0; double num8 = num7 / num; double num9 = random.NextDouble() * 2.0 - 1.0; num3 += 0.035 * (num9 - num3); double num10 = Math.Sin(Math.PI * 2.0 * (22.0 + (double)variant * 3.7) * num7); double num11 = Frequency[variant] * (1.18 - 0.62 * num8) * (1.0 + 0.13 * num10 + 0.45 * num3); if (variant == 5) { num11 *= 1.0 + 0.35 * Math.Sin(Math.PI * 6.0 * num7); } num2 += Math.PI * 2.0 * num11 / 22050.0; double num12 = Math.Tanh(2.9 * (Math.Sin(num2) + 0.38 * Math.Sin(2.0 * num2 + 0.5))); double num13 = ((variant == 2 || variant == 6) ? (0.18 + 0.82 * Math.Pow(0.5 + 0.5 * Math.Sin(Math.PI * 2.0 * (double)(7 + variant) * num7), 1.8)) : (0.65 + 0.35 * (0.5 + 0.5 * num10))); double num14 = Math.Min(1.0, num7 / 0.012) * Math.Pow(Math.Max(0.0, 1.0 - num8), 0.65) * Math.Min(1.0, (num - num7) / 0.055) * num13 * (0.7 * num12 + 0.28 * num9 + 1.8 * num3); num5 = 0.992 * (num5 + num14 - num4); num4 = num14; array[i] = (float)num5; num6 = Math.Max(num6, Math.Abs(array[i])); } if (num6 > 0f) { for (int j = 0; j < array.Length; j++) { array[j] *= 0.78f / num6; } } array[0] = (array[^1] = 0f); return array; } } internal static class JetRules { internal const float Duration = 0.55f; internal const float InitialSpeed = 8f; internal static float SpeedAt(float elapsed) { if (float.IsNaN(elapsed) || elapsed < 0f || elapsed >= 0.55f) { return 0f; } return 8f * (1f - elapsed / 0.55f); } } [HarmonyPatch(typeof(Player), "Awake")] internal static class PlayerAudioPatch { private static void Postfix(Player __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<MatveyAudio>())) { ((Component)__instance).gameObject.AddComponent<MatveyAudio>(); } } } public sealed class MatveyAudio : MonoBehaviour { private const string PlayRpc = "Matvey_PlayFart_v1"; private const string StopRpc = "Matvey_StopFart_v1"; private ZNetView view; private Player player; private AudioSource source; private ParticleSystem gas; private bool registered; private float lastPlay = -100f; private bool usesMixer; private void Start() { Initialize(); } private bool Initialize() { if (registered) { return true; } view = ((Component)this).GetComponent<ZNetView>(); player = ((Component)this).GetComponent<Player>(); if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !Object.op_Implicit((Object)(object)player)) { return false; } view.Register<int, float>("Matvey_PlayFart_v1", (Action<long, int, float>)ReceivePlay); view.Register("Matvey_StopFart_v1", (Action<long>)ReceiveStop); registered = true; return true; } internal void Broadcast(int clip, float pitch) { if (Initialize() && view.IsOwner()) { view.InvokeRPC(ZNetView.Everybody, "Matvey_PlayFart_v1", new object[2] { clip, pitch }); } } internal void BroadcastStop() { if (Initialize() && view.IsOwner()) { view.InvokeRPC(ZNetView.Everybody, "Matvey_StopFart_v1", Array.Empty<object>()); } } private bool FromOwner(long sender) { if (Object.op_Implicit((Object)(object)view) && view.IsValid()) { return sender == view.GetZDO().GetOwner(); } return false; } private void ReceivePlay(long sender, int clip, float pitch) { //IL_00ee: 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) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) if (!FromOwner(sender) || !Object.op_Implicit((Object)(object)player) || ((Character)player).IsDead() || Application.isBatchMode || Plugin.Sounds == null || clip < 0 || clip >= Plugin.Sounds.Length || float.IsNaN(pitch) || float.IsInfinity(pitch) || Time.unscaledTime - lastPlay < 2f) { return; } lastPlay = Time.unscaledTime; EnsureSource(); source.clip = Plugin.Sounds[clip]; source.pitch = Mathf.Clamp(pitch, 0.9f, 1.1f); source.volume = Plugin.SoundVolume.Value * (usesMixer ? 1f : AudioMan.GetSFXVolume()); source.Play(); if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Vector3 val = ((Component)Player.m_localPlayer).transform.position - ((Component)this).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude <= 1225f)) { return; } } if (!Object.op_Implicit((Object)(object)gas)) { gas = MatveyGas.Create(((Component)this).transform); } MatveyGas.Play(gas, ((Component)this).transform); } private void ReceiveStop(long sender) { if (FromOwner(sender)) { if (Object.op_Implicit((Object)(object)source)) { source.Stop(); } if (Object.op_Implicit((Object)(object)gas)) { gas.Stop(true, (ParticleSystemStopBehavior)0); } } } private void EnsureSource() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)source)) { return; } GameObject val = new GameObject("MatveyAudio"); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = new Vector3(0f, 0.8f, 0f); source = val.AddComponent<AudioSource>(); source.playOnAwake = false; source.loop = false; source.spatialBlend = 1f; source.dopplerLevel = 0f; source.minDistance = 2f; source.maxDistance = 18f; source.rolloffMode = (AudioRolloffMode)1; if (Object.op_Implicit((Object)(object)AudioMan.instance) && Object.op_Implicit((Object)(object)AudioMan.instance.m_masterMixer)) { AudioMixerGroup[] array = AudioMan.instance.m_masterMixer.FindMatchingGroups("SFX"); if (array.Length != 0) { source.outputAudioMixerGroup = array[0]; usesMixer = true; } } } private void Update() { if (Object.op_Implicit((Object)(object)player) && ((Character)player).IsDead()) { if (Object.op_Implicit((Object)(object)source) && source.isPlaying) { source.Stop(); } if (Object.op_Implicit((Object)(object)gas) && gas.IsAlive()) { gas.Stop(true, (ParticleSystemStopBehavior)0); } } } } internal static class MatveyGas { private static Material material; private static Texture2D texture; private static bool attempted; private static bool Prepare() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) if (attempted) { return Object.op_Implicit((Object)(object)material); } attempted = true; Shader val = Shader.Find("Particles/Standard Unlit"); Material val2 = null; if (!Object.op_Implicit((Object)(object)val) || !val.isSupported) { ParticleSystemRenderer[] array = Resources.FindObjectsOfTypeAll<ParticleSystemRenderer>(); for (int i = 0; i < array.Length; i++) { Material sharedMaterial = ((Renderer)array[i]).sharedMaterial; if (Object.op_Implicit((Object)(object)sharedMaterial) && Object.op_Implicit((Object)(object)sharedMaterial.shader) && sharedMaterial.shader.isSupported && ((Object)sharedMaterial.shader).name.ToLowerInvariant().Contains("particle") && sharedMaterial.HasProperty("_MainTex")) { val2 = sharedMaterial; val = sharedMaterial.shader; break; } } } if (!Object.op_Implicit((Object)(object)val) || !val.isSupported) { Plugin instance = Plugin.Instance; if (instance != null) { instance.LoggerForEffects.LogWarning((object)"No supported particle shader for Matvey gas; audio and movement remain available."); } return false; } texture = new Texture2D(32, 32, (TextureFormat)4, false) { name = "Matvey soft gas opacity", wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color[] array2 = (Color[])(object)new Color[1024]; for (int j = 0; j < 32; j++) { for (int k = 0; k < 32; k++) { float num = ((float)k - 15.5f) / 15.5f; float num2 = ((float)j - 15.5f) / 15.5f; float num3 = Mathf.Pow(Mathf.Clamp01(1f - num * num - num2 * num2), 1.5f); array2[j * 32 + k] = new Color(1f, 1f, 1f, num3); } } texture.SetPixels(array2); texture.Apply(false, true); material = (Object.op_Implicit((Object)(object)val2) ? new Material(val2) : new Material(val)); ((Object)material).name = "Matvey green gas"; material.mainTexture = (Texture)(object)texture; material.mainTextureScale = Vector2.one; material.mainTextureOffset = Vector2.zero; material.renderQueue = 3000; string[] array3 = new string[5] { "_ALPHATEST_ON", "_ALPHAPREMULTIPLY_ON", "_EMISSION", "_NORMALMAP", "_FADING_ON" }; foreach (string text in array3) { material.DisableKeyword(text); } material.EnableKeyword("_ALPHABLEND_ON"); if (material.HasProperty("_Mode")) { material.SetFloat("_Mode", 2f); } if (material.HasProperty("_SrcBlend")) { material.SetInt("_SrcBlend", 5); } if (material.HasProperty("_DstBlend")) { material.SetInt("_DstBlend", 10); } if (material.HasProperty("_ZWrite")) { material.SetInt("_ZWrite", 0); } if (material.HasProperty("_Cull")) { material.SetInt("_Cull", 0); } array3 = new string[3] { "_Color", "_TintColor", "_BaseColor" }; foreach (string text2 in array3) { if (material.HasProperty(text2)) { material.SetColor(text2, Color.white); } } return true; } internal static ParticleSystem Create(Transform player) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) if (!Prepare()) { return null; } GameObject val = new GameObject("Matvey green puff"); val.transform.SetParent(player, false); val.transform.localPosition = new Vector3(0f, 0.85f, -0.35f); ParticleSystem val2 = val.AddComponent<ParticleSystem>(); val2.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = val2.main; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).duration = 1.2f; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.05f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.5f); ((MainModule)(ref main)).maxParticles = 24; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).enabled = false; ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val3 = new Gradient(); val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(new Color(0.65f, 0.75f, 0.4f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(1f, 0.12f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3); SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, new AnimationCurve((Keyframe[])(object)new Keyframe[2] { new Keyframe(0f, 0.6f), new Keyframe(1f, 1.9f) })); ParticleSystemRenderer component = ((Component)val2).GetComponent<ParticleSystemRenderer>(); component.renderMode = (ParticleSystemRenderMode)0; ((Renderer)component).sharedMaterial = material; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; return val2; } internal static void Play(ParticleSystem particles, Transform player) { //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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)particles)) { particles.Stop(true, (ParticleSystemStopBehavior)0); particles.Play(); Vector3 val = Vector3.ProjectOnPlane(player.forward, Vector3.up); Vector3 val2 = -((Vector3)(ref val)).normalized; for (int i = 0; i < 10; i++) { EmitParams val3 = default(EmitParams); ((EmitParams)(ref val3)).position = ((Component)particles).transform.position + Random.insideUnitSphere * 0.09f; ((EmitParams)(ref val3)).velocity = val2 * Random.Range(0.7f, 1.7f) + player.right * Random.Range(-0.3f, 0.3f) + Vector3.up * Random.Range(0.15f, 0.4f); ((EmitParams)(ref val3)).startLifetime = Random.Range(0.75f, 1.05f); ((EmitParams)(ref val3)).startSize = Random.Range(0.4f, 0.7f); ((EmitParams)(ref val3)).startColor = Color32.op_Implicit(new Color(Random.Range(0.43f, 0.58f), Random.Range(0.62f, 0.76f), 0.12f, 0.8f)); ((EmitParams)(ref val3)).rotation = Random.Range(0f, 360f); EmitParams val4 = val3; particles.Emit(val4, 1); } } } internal static void Cleanup() { if (Object.op_Implicit((Object)(object)material)) { Object.Destroy((Object)(object)material); } if (Object.op_Implicit((Object)(object)texture)) { Object.Destroy((Object)(object)texture); } material = null; texture = null; attempted = false; } } [HarmonyPatch(typeof(Character), "AddPushbackForce")] internal static class MatveyJetPatch { private static readonly int EffectHash = StringExtensionMethods.GetStableHashCode("SE_MatveySendsRegards"); private static void Postfix(Character __instance, ref Vector3 velocity) { if (__instance is Player && __instance.IsOwner() && !__instance.IsDead()) { SEMan sEMan = __instance.GetSEMan(); (((sEMan != null) ? sEMan.GetStatusEffect(EffectHash) : null) as SE_Matvey)?.ApplyJet(ref velocity); } } } [BepInPlugin("local.matvey.fartingmead", "Farting Matvey", "1.0.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "local.matvey.fartingmead"; public const string MeadName = "MeadMatvey"; public const string BaseName = "MeadBaseMatvey"; public const string EffectName = "SE_MatveySendsRegards"; internal static Plugin Instance; internal static ConfigEntry<float> SoundVolume; internal static AudioClip[] Sounds; internal static float[] SoundDurations; internal static Sprite StatusIcon; private Harmony harmony; private Sprite baseIcon; private Sprite meadIcon; private ConfigEntry<int> iconVariant; private SE_Matvey effect; private readonly List<Object> ownedAssets = new List<Object>(); internal ManualLogSource LoggerForEffects => ((BaseUnityPlugin)this).Logger; private void Awake() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown Instance = this; iconVariant = ((BaseUnityPlugin)this).Config.Bind<int>("Visuals", "StatusIcon", 1, new ConfigDescription("1 = Matvey mead with green foam; 2 = tipsy swirl; 3 = green cloud. Applied after restarting the game.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>())); SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.65f, new ConfigDescription("Local sound volume, additionally controlled by the game's SFX volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); AddLocalization(); baseIcon = LoadSprite("mead-base.png"); meadIcon = LoadSprite("mead.png"); StatusIcon = LoadSprite("status-" + iconVariant.Value + ".png"); effect = ScriptableObject.CreateInstance<SE_Matvey>(); ((Object)effect).name = "SE_MatveySendsRegards"; ((StatusEffect)effect).m_name = "$matvey_effect"; ((StatusEffect)effect).m_icon = StatusIcon; ((StatusEffect)effect).m_ttl = 100f; ((StatusEffect)effect).m_hidden = false; ((StatusEffect)effect).m_flashIcon = false; ((StatusEffect)effect).m_startMessageType = (MessageType)2; ((StatusEffect)effect).m_startMessage = "$matvey_effect"; ((StatusEffect)effect).m_stopMessage = "$matvey_finished"; ((StatusEffect)effect).m_stopMessageType = (MessageType)1; ((StatusEffect)effect).m_startEffects = new EffectList(); ((StatusEffect)effect).m_stopEffects = new EffectList(); if (!ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)effect, false))) { throw new InvalidOperationException("Could not register the Matvey status effect."); } ownedAssets.Add((Object)(object)effect); if (!Application.isBatchMode) { CreateSounds(); } harmony = new Harmony("local.matvey.fartingmead"); harmony.PatchAll(typeof(Plugin).Assembly); PrefabManager.OnVanillaPrefabsAvailable += RegisterItems; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Matvey ready: 100 seconds, movement -30%, reactive forward bursts and green gas, 8 sound variants, HUD icon " + iconVariant.Value)); } private Sprite LoadSprite(string file) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FartingMatvey.Assets." + file); if (stream == null) { throw new FileNotFoundException("Missing embedded icon", file); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { throw new InvalidDataException("Invalid icon " + file); } ((Object)val).name = "Matvey_" + file; ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)val2).name = "Matvey_" + file; ownedAssets.Add((Object)(object)val); ownedAssets.Add((Object)(object)val2); return val2; } private void CreateSounds() { Sounds = (AudioClip[])(object)new AudioClip[8]; SoundDurations = new float[8]; string directory = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Sounds"); for (int i = 0; i < Sounds.Length; i++) { string text = "matvey-" + (i + 1).ToString("00") + ".wav"; WaveSamples waveSamples = LoadSound(i, directory, text); AudioClip val = AudioClip.Create("Matvey_fart_" + (i + 1), waveSamples.Frames, waveSamples.Channels, waveSamples.SampleRate, false); ownedAssets.Add((Object)(object)val); if (!val.SetData(waveSamples.Samples, 0)) { throw new InvalidOperationException("Could not load sound " + text); } Sounds[i] = val; SoundDurations[i] = waveSamples.Duration; } } private WaveSamples LoadSound(int variant, string directory, string file) { string path = Path.Combine(directory, file); if (File.Exists(path)) { try { using Stream stream = File.OpenRead(path); WaveSamples waveSamples = WaveSamples.Read(stream); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Custom sound " + file + ": " + waveSamples.Duration.ToString("0.000") + " seconds.")); return waveSamples; } catch (Exception ex) when (ex is IOException || ex is InvalidDataException || ex is UnauthorizedAccessException || ex is ArgumentException) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read " + file + "; using the bundled sound. " + ex.Message)); } } using (Stream stream2 = Assembly.GetExecutingAssembly().GetManifestResourceStream("FartingMatvey.Assets.Sounds." + file)) { if (stream2 != null) { return WaveSamples.Read(stream2); } } return new WaveSamples(FartSynthesis.Create(variant), 1, 22050); } private void RegisterItems() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterItems; try { string[] array = new string[8] { "MeadPoisonResist", "MeadBasePoisonResist", "Honey", "Mushroom", "Ooze", "Pukeberries", "piece_MeadCauldron", "fermenter" }; foreach (string text in array) { if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(text))) { throw new InvalidOperationException("Missing vanilla prefab: " + text); } } CustomItem val = new CustomItem("MeadMatvey", "MeadPoisonResist"); SharedData shared = val.ItemDrop.m_itemData.m_shared; shared.m_name = "$item_matvey"; shared.m_description = "$item_matvey_description"; shared.m_icons = (Sprite[])(object)new Sprite[1] { meadIcon }; shared.m_consumeStatusEffect = (StatusEffect)(object)effect; shared.m_maxStackSize = 10; shared.m_food = 0f; shared.m_foodStamina = 0f; shared.m_foodEitr = 0f; if (!ItemManager.Instance.AddItem(val)) { throw new InvalidOperationException("Could not add MeadMatvey"); } ItemConfig val2 = new ItemConfig { Name = "$item_matveybase", Description = "$item_matveybase_description", CraftingStation = "piece_MeadCauldron", MinStationLevel = 1, Amount = 1, Icon = baseIcon }; val2.AddRequirement("Honey", 5, 0); val2.AddRequirement("Mushroom", 2, 0); val2.AddRequirement("Ooze", 1, 0); val2.AddRequirement("Pukeberries", 1, 0); CustomItem val3 = new CustomItem("MeadBaseMatvey", "MeadBasePoisonResist", val2); if (!ItemManager.Instance.AddItem(val3)) { throw new InvalidOperationException("Could not add MeadBaseMatvey"); } if (!ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)new FermenterConversionConfig { FromItem = "MeadBaseMatvey", ToItem = "MeadMatvey", Station = Fermenters.Fermenter, ProducedItems = 6 }))) { throw new InvalidOperationException("Could not register Matvey fermentation."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered MeadBaseMatvey -> 6 MeadMatvey. Recipe: Honey 5, Mushroom 2, Ooze 1, Pukeberries 1."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Matvey item registration failed: " + ex)); } } private void AddLocalization() { Dictionary<string, string> dictionary = new Dictionary<string, string> { ["item_matvey"] = "Пердящий Матвей", ["item_matvey_description"] = "Матвей уверял, что это нормальный осадок. На 100 секунд: скорость передвижения −30%, периодические залпы со звуком, зелёным облаком и коротким толчком вперёд на земле.", ["item_matveybase"] = "Основа медовухи: Пердящий Матвей", ["item_matveybase_description"] = "Мёд, грибы, слизь и рвотная ягода. Требует брожения. Готовая медовуха на 100 секунд снижает скорость на 30% и вызывает залпы с зелёным облаком и коротким толчком вперёд на земле. Бочка уже жалеет, что согласилась.", ["matvey_effect"] = "Матвей передаёт привет", ["matvey_tooltip"] = "Скорость передвижения −30%\nРеактивные залпы: короткий толчок вперёд на земле, звук и зелёное облако.\nДлительность: 100 секунд.", ["matvey_finished"] = "Матвей попрощался." }; CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, dictionary); text = "Russian"; localization.AddTranslation(ref text, dictionary); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterItems; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } MatveyGas.Cleanup(); foreach (Object ownedAsset in ownedAssets) { if (Object.op_Implicit(ownedAsset)) { Object.Destroy(ownedAsset); } } Sounds = null; SoundDurations = null; Instance = null; } } public sealed class SE_Matvey : StatusEffect { private FartSchedule schedule; private float jetElapsed = 0.55f; private Vector3 jetDirection; public override bool CanAdd(Character character) { return character is Player; } public override void Setup(Character character) { ((StatusEffect)this).Setup(character); schedule = new FartSchedule(new Random(Environment.TickCount ^ ((Object)character).GetInstanceID()), Plugin.SoundDurations); CancelJet(); } public override void ResetTime() { ((StatusEffect)this).ResetTime(); schedule?.Reset(); CancelJet(); } public override void UpdateStatusEffect(float dt) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) ((StatusEffect)this).UpdateStatusEffect(dt); jetElapsed = Mathf.Min(0.55f, jetElapsed + dt); if (Object.op_Implicit((Object)(object)base.m_character) && !base.m_character.IsDead() && base.m_character.IsOwner() && !((StatusEffect)this).IsDone() && schedule != null && schedule.TryNext(base.m_time, out var clip, out var pitch)) { if (CanJet()) { Vector3 val = Vector3.ProjectOnPlane(((Component)base.m_character).transform.forward, Vector3.up); jetDirection = ((Vector3)(ref val)).normalized; jetElapsed = 0f; } ((Component)base.m_character).GetComponent<MatveyAudio>()?.Broadcast(clip, pitch); } } private bool CanJet() { if (Object.op_Implicit((Object)(object)base.m_character) && base.m_character.IsOwner() && !((StatusEffect)this).IsDone() && base.m_character.IsOnGround() && !base.m_character.IsAttached() && !base.m_character.IsTeleporting() && !base.m_character.InCutscene() && !base.m_character.InIntro() && !base.m_character.IsDebugFlying()) { return !base.m_character.IsKnockedBack(); } return false; } internal void ApplyJet(ref Vector3 velocity) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) float num = JetRules.SpeedAt(jetElapsed); if (!(num <= 0f)) { if (!CanJet()) { CancelJet(); } else { velocity += jetDirection * num; } } } private void CancelJet() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) jetElapsed = 0.55f; jetDirection = Vector3.zero; } public override bool IsDone() { if (!(base.m_time >= base.m_ttl)) { if (Object.op_Implicit((Object)(object)base.m_character)) { return base.m_character.IsDead(); } return false; } return true; } public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir) { if (!((StatusEffect)this).IsDone()) { speed = EffectRules.ApplySpeed(baseSpeed, speed); } } public override string GetTooltipString() { return Localization.instance.Localize("$matvey_tooltip"); } public override void Stop() { schedule = null; CancelJet(); if (Object.op_Implicit((Object)(object)base.m_character) && base.m_character.IsOwner()) { ((Component)base.m_character).GetComponent<MatveyAudio>()?.BroadcastStop(); } ((StatusEffect)this).Stop(); } } internal sealed class WaveSamples { internal const int MaximumFileBytes = 16777216; internal const float MaximumDuration = 15f; internal float[] Samples { get; } internal int Channels { get; } internal int SampleRate { get; } internal int Frames => Samples.Length / Channels; internal float Duration => (float)Frames / (float)SampleRate; internal WaveSamples(float[] samples, int channels, int sampleRate) { Samples = samples; Channels = channels; SampleRate = sampleRate; } internal static WaveSamples Read(Stream stream) { if (!stream.CanRead || !stream.CanSeek || stream.Length < 44 || stream.Length > 16777216) { throw new InvalidDataException("WAV must be a readable file no larger than 16 MiB."); } stream.Position = 0L; using BinaryReader binaryReader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true); if (FourCC(binaryReader) != "RIFF") { throw new InvalidDataException("Expected RIFF WAV."); } long num = 8L + (long)binaryReader.ReadUInt32(); if (num < 44 || num > stream.Length || FourCC(binaryReader) != "WAVE") { throw new InvalidDataException("Invalid or truncated WAV header."); } bool flag = false; int num2 = 0; int num3 = 0; int num4 = 0; long num5 = -1L; uint num6 = 0u; while (stream.Position + 8 <= num) { string text = FourCC(binaryReader); uint num7 = binaryReader.ReadUInt32(); long position = stream.Position; long num8 = position + num7 + (num7 & 1); if (num8 > num) { throw new InvalidDataException("Truncated WAV chunk."); } if (text == "fmt ") { if (flag || num7 < 16) { throw new InvalidDataException("Invalid WAV format chunk."); } flag = true; ushort num9 = binaryReader.ReadUInt16(); num2 = binaryReader.ReadUInt16(); uint num10 = binaryReader.ReadUInt32(); uint num11 = binaryReader.ReadUInt32(); num4 = binaryReader.ReadUInt16(); ushort num12 = binaryReader.ReadUInt16(); if (num9 != 1 || num12 != 16 || (num2 != 1 && num2 != 2)) { throw new InvalidDataException("Export as WAV PCM 16-bit, mono or stereo."); } if (num10 < 8000 || num10 > 192000 || num4 != num2 * 2 || num11 != num10 * num4) { throw new InvalidDataException("Invalid WAV sample rate or frame size."); } num3 = (int)num10; } else if (text == "data") { if (num5 >= 0) { throw new InvalidDataException("Multiple WAV data chunks are unsupported."); } num5 = position; num6 = num7; } stream.Position = num8; } if (stream.Position != num || !flag || num5 < 0 || num6 == 0 || num6 % num4 != 0L) { throw new InvalidDataException("Missing or incomplete WAV audio data."); } if ((double)num6 / (double)num4 / (double)num3 > 15.0) { throw new InvalidDataException("Sound must be at most 15 seconds long."); } stream.Position = num5; float[] array = new float[(int)num6 / 2]; for (int i = 0; i < array.Length; i++) { array[i] = (float)binaryReader.ReadInt16() / 32768f; } return new WaveSamples(array, num2, num3); } private static string FourCC(BinaryReader reader) { return Encoding.ASCII.GetString(reader.ReadBytes(4)); } } }
BepInEx/plugins/FireBelchMead/FireBelchMead.dll
Decompiled 10 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FireBelchMead")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FireBelchMead")] [assembly: AssemblyTitle("FireBelchMead")] [assembly: AssemblyVersion("1.0.0.0")] [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 FireBelchMead { [HarmonyPatch(typeof(Player), "Awake")] internal static class PlayerBelchPatch { private static void Postfix(Player __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<BelchEmitter>())) { ((Component)__instance).gameObject.AddComponent<BelchEmitter>(); } } } public sealed class BelchEmitter : MonoBehaviour { private const string VisualRpc = "FireBelch_Visual_v1"; private ZNetView view; private Player player; private AudioSource source; private ParticleSystem smoke; private ParticleSystem flames; private bool registered; private bool usesMixer; private readonly float[] lastVisual = new float[2] { -100f, -100f }; private float lastAttack = -100f; private void Start() { Initialize(); } private bool Initialize() { if (registered) { return true; } view = ((Component)this).GetComponent<ZNetView>(); player = ((Component)this).GetComponent<Player>(); if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !Object.op_Implicit((Object)(object)player)) { return false; } view.Register<int, Vector3>("FireBelch_Visual_v1", (Action<long, int, Vector3>)ReceiveVisual); registered = true; return true; } internal void Broadcast(int phase) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (Initialize() && view.IsOwner()) { SendVisual(phase, Direction()); } } internal void Fire() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_01c3: Expected O, but got Unknown if (!Initialize() || !view.IsOwner() || ((Character)player).IsDead() || Time.time - lastAttack < 14f) { return; } lastAttack = Time.time; Vector3 val = Direction(); Vector3 val2 = Mouth(val); SendVisual(1, val); Character[] array = Character.GetAllCharacters().ToArray(); foreach (Character val3 in array) { if (!Object.op_Implicit((Object)(object)val3) || (Object)(object)val3 == (Object)(object)player || val3 is Player || val3.IsDead() || val3.IsTamed() || !BaseAI.IsEnemy((Character)(object)player, val3)) { continue; } Collider collider = (Collider)(object)val3.GetCollider(); if (!Object.op_Implicit((Object)(object)collider) || !collider.enabled) { continue; } Vector3 val4 = val3.GetCenterPoint() - val2; if (!(((Vector3)(ref val4)).sqrMagnitude > (4f + val3.GetRadius() + val3.GetHeight()) * (4f + val3.GetRadius() + val3.GetHeight()))) { float num = Mathf.Clamp(Vector3.Dot(val4, val), 0f, 4f); Vector3 val5 = collider.ClosestPoint(val2 + val * num); Vector3 val6 = val5 - val2; if (EffectRules.InCone(((Vector3)(ref val6)).sqrMagnitude, Vector3.Dot(val6, val)) && !BlockedByWorld(val2, val6)) { HitData val7 = new HitData { m_point = val5, m_dir = val, m_hitCollider = collider, m_blockable = true, m_dodgeable = true, m_pushForce = 0f, m_skill = (SkillType)0 }; val7.m_damage.m_fire = 30f; val7.SetAttacker((Character)(object)player); val3.Damage(val7); } } } } private static bool BlockedByWorld(Vector3 origin, Vector3 delta) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) float magnitude = ((Vector3)(ref delta)).magnitude; if (magnitude < 0.01f) { return false; } RaycastHit[] array = Physics.RaycastAll(origin, delta / magnitude, magnitude, -5, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>())) { return true; } } return false; } private Vector3 Direction() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Vector3 lookDir = ((Character)player).GetLookDir(); if (!(((Vector3)(ref lookDir)).sqrMagnitude > 0.01f)) { return ((Component)this).transform.forward; } return ((Vector3)(ref lookDir)).normalized; } private Vector3 Mouth(Vector3 direction) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) return ((Character)player).GetEyePoint() - Vector3.up * 0.13f + direction * 0.13f; } private void SendVisual(int phase, Vector3 direction) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) view.InvokeRPC(ZNetView.Everybody, "FireBelch_Visual_v1", new object[2] { phase, direction }); } private void ReceiveVisual(long sender, int phase, Vector3 direction) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || sender != view.GetZDO().GetOwner() || !Object.op_Implicit((Object)(object)player) || ((Character)player).IsDead() || Application.isBatchMode || phase < 0 || phase > 1 || !Finite(direction.x) || !Finite(direction.y) || !Finite(direction.z) || ((Vector3)(ref direction)).sqrMagnitude < 0.5f || ((Vector3)(ref direction)).sqrMagnitude > 2f || Time.unscaledTime - lastVisual[phase] < 10f) { return; } lastVisual[phase] = Time.unscaledTime; if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Vector3 val = ((Component)Player.m_localPlayer).transform.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 1600f) { return; } } ((Vector3)(ref direction)).Normalize(); EnsureSource(); ((Component)source).transform.position = Mouth(direction); if (Plugin.Sounds != null && Object.op_Implicit((Object)(object)Plugin.Sounds[phase])) { source.clip = Plugin.Sounds[phase]; source.volume = Plugin.SoundVolume.Value * (usesMixer ? 1f : AudioMan.GetSFXVolume()); source.Play(); } if (phase == 0) { if (!Object.op_Implicit((Object)(object)smoke)) { smoke = BelchVfx.Create(((Component)this).transform, fire: false); } BelchVfx.Emit(smoke, Mouth(direction), direction, fire: false); } else { if (!Object.op_Implicit((Object)(object)flames)) { flames = BelchVfx.Create(((Component)this).transform, fire: true); } BelchVfx.Emit(flames, Mouth(direction), direction, fire: true); } } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private void EnsureSource() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)source)) { return; } GameObject val = new GameObject("Fire Belch audio"); val.transform.SetParent(((Component)this).transform, false); source = val.AddComponent<AudioSource>(); source.playOnAwake = false; source.loop = false; source.spatialBlend = 1f; source.dopplerLevel = 0f; source.minDistance = 2f; source.maxDistance = 20f; source.rolloffMode = (AudioRolloffMode)1; if (Object.op_Implicit((Object)(object)AudioMan.instance) && Object.op_Implicit((Object)(object)AudioMan.instance.m_masterMixer)) { AudioMixerGroup[] array = AudioMan.instance.m_masterMixer.FindMatchingGroups("SFX"); if (array.Length != 0) { source.outputAudioMixerGroup = array[0]; usesMixer = true; } } } private void Update() { if (Object.op_Implicit((Object)(object)player) && ((Character)player).IsDead()) { if (Object.op_Implicit((Object)(object)source) && source.isPlaying) { source.Stop(); } if (Object.op_Implicit((Object)(object)smoke) && smoke.IsAlive()) { smoke.Stop(true, (ParticleSystemStopBehavior)0); } if (Object.op_Implicit((Object)(object)flames) && flames.IsAlive()) { flames.Stop(true, (ParticleSystemStopBehavior)0); } } } } internal static class BelchSynthesis { internal const int SampleRate = 44100; internal static float[] Create(bool fire) { double num = (fire ? 1.05 : 0.22); float[] array = new float[(int)(44100.0 * num)]; Random random = new Random(fire ? 417 : 19); double num2 = 0.0; double num3 = 0.0; for (int i = 0; i < array.Length; i++) { double num4 = (double)i / 44100.0; double num5 = num4 / num; double num6 = (fire ? (83.0 - 37.0 * num5 + 9.0 * Math.Sin(37.0 * num4)) : (190.0 - 85.0 * num5)); num2 += Math.PI * 2.0 * num6 / 44100.0; double num7 = random.NextDouble() * 2.0 - 1.0; num3 = 0.89 * num3 + 0.11 * num7; double num8 = Math.Sin(num2) * 0.46 + Math.Sin(num2 * 2.04) * 0.22 + Math.Sin(num2 * 3.01) * 0.13; double num9 = Math.Min(1.0, num4 / 0.018) * Math.Pow(1.0 - num5, fire ? 1.15 : 1.9); double num10 = (fire ? (0.18 * num7 + 1.6 * num3) : (0.07 * num7)); array[i] = (float)(0.76 * Math.Tanh((num8 + num10) * (fire ? 1.8 : 1.1)) * num9); } return array; } } internal static class BelchVfx { private static Material material; private static Texture2D texture; private static bool attempted; private static bool Prepare() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_01d3: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0205: 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) if (attempted) { return Object.op_Implicit((Object)(object)material); } attempted = true; Shader val = Shader.Find("Particles/Standard Unlit"); Material val2 = null; if (!Object.op_Implicit((Object)(object)val) || !val.isSupported) { ParticleSystemRenderer[] array = Resources.FindObjectsOfTypeAll<ParticleSystemRenderer>(); for (int i = 0; i < array.Length; i++) { Material sharedMaterial = ((Renderer)array[i]).sharedMaterial; if (Object.op_Implicit((Object)(object)sharedMaterial) && Object.op_Implicit((Object)(object)sharedMaterial.shader) && sharedMaterial.shader.isSupported && ((Object)sharedMaterial.shader).name.ToLowerInvariant().Contains("particle") && sharedMaterial.HasProperty("_MainTex")) { val2 = sharedMaterial; val = sharedMaterial.shader; break; } } } if (!Object.op_Implicit((Object)(object)val) || !val.isSupported) { Plugin instance = Plugin.Instance; if (instance != null) { instance.LoggerForEffects.LogWarning((object)"No supported particle shader for fire belch."); } return false; } texture = new Texture2D(32, 32, (TextureFormat)4, false) { name = "FireBelch soft opacity", wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color[] array2 = (Color[])(object)new Color[1024]; for (int j = 0; j < 32; j++) { for (int k = 0; k < 32; k++) { float num = ((float)k - 15.5f) / 15.5f; float num2 = ((float)j - 15.5f) / 15.5f; array2[j * 32 + k] = new Color(1f, 1f, 1f, Mathf.Pow(Mathf.Clamp01(1f - num * num - num2 * num2), 1.5f)); } } texture.SetPixels(array2); texture.Apply(false, true); material = (Object.op_Implicit((Object)(object)val2) ? new Material(val2) : new Material(val)); ((Object)material).name = "FireBelch particles"; material.mainTexture = (Texture)(object)texture; material.mainTextureScale = Vector2.one; material.mainTextureOffset = Vector2.zero; material.renderQueue = 3000; string[] array3 = new string[5] { "_ALPHATEST_ON", "_ALPHAPREMULTIPLY_ON", "_EMISSION", "_NORMALMAP", "_FADING_ON" }; foreach (string text in array3) { material.DisableKeyword(text); } material.EnableKeyword("_ALPHABLEND_ON"); if (material.HasProperty("_Mode")) { material.SetFloat("_Mode", 2f); } if (material.HasProperty("_SrcBlend")) { material.SetInt("_SrcBlend", 5); } if (material.HasProperty("_DstBlend")) { material.SetInt("_DstBlend", 10); } if (material.HasProperty("_ZWrite")) { material.SetInt("_ZWrite", 0); } if (material.HasProperty("_Cull")) { material.SetInt("_Cull", 0); } array3 = new string[3] { "_Color", "_TintColor", "_BaseColor" }; foreach (string text2 in array3) { if (material.HasProperty(text2)) { material.SetColor(text2, Color.white); } } return true; } internal static ParticleSystem Create(Transform parent, bool fire) { //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_0039: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0255: 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_0269: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) if (!Prepare()) { return null; } GameObject val = new GameObject(fire ? "Fire Belch flames" : "Fire Belch hiccup smoke"); val.transform.SetParent(parent, false); ParticleSystem val2 = val.AddComponent<ParticleSystem>(); val2.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = val2.main; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).duration = 1f; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.5f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).maxParticles = 80; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).enabled = false; Gradient val3 = new Gradient(); val3.SetKeys((GradientColorKey[])(object)((!fire) ? new GradientColorKey[2] { new GradientColorKey(new Color(0.6f, 0.54f, 0.48f), 0f), new GradientColorKey(new Color(0.33f, 0.3f, 0.28f), 1f) } : new GradientColorKey[3] { new GradientColorKey(new Color(1f, 0.95f, 0.5f), 0f), new GradientColorKey(new Color(1f, 0.38f, 0.035f), 0.45f), new GradientColorKey(new Color(0.35f, 0.06f, 0.015f), 1f) }), (GradientAlphaKey[])(object)new GradientAlphaKey[4] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(0.85f, 0.08f), new GradientAlphaKey(0.55f, 0.6f), new GradientAlphaKey(0f, 1f) }); ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3); SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, new AnimationCurve((Keyframe[])(object)new Keyframe[3] { new Keyframe(0f, 0.45f), new Keyframe(0.6f, 1.2f), new Keyframe(1f, 1.8f) })); ParticleSystemRenderer component = ((Component)val2).GetComponent<ParticleSystemRenderer>(); component.renderMode = (ParticleSystemRenderMode)0; ((Renderer)component).sharedMaterial = material; ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = false; return val2; } internal static void Emit(ParticleSystem particles, Vector3 origin, Vector3 direction, bool fire) { //IL_0017: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00c5: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)particles)) { return; } particles.Stop(true, (ParticleSystemStopBehavior)0); particles.Play(); Quaternion val = Quaternion.LookRotation(direction); int num = (fire ? 60 : 10); for (int i = 0; i < num; i++) { Vector2 insideUnitCircle = Random.insideUnitCircle; float num2 = Random.Range(fire ? 5.5f : 0.35f, fire ? 8f : 0.8f); float num3 = (fire ? 0.55f : 0.3f); Vector3 val2 = new Vector3(insideUnitCircle.x * num3, insideUnitCircle.y * num3, 1f); Vector3 val3 = val * ((Vector3)(ref val2)).normalized * num2; if (!fire) { val3 += Vector3.up * 0.3f; } EmitParams val4 = default(EmitParams); ((EmitParams)(ref val4)).position = origin + Random.insideUnitSphere * 0.035f; ((EmitParams)(ref val4)).velocity = val3; ((EmitParams)(ref val4)).startLifetime = (fire ? Random.Range(0.28f, 0.5f) : Random.Range(0.5f, 0.8f)); ((EmitParams)(ref val4)).startSize = (fire ? Random.Range(0.18f, 0.5f) : Random.Range(0.12f, 0.22f)); ((EmitParams)(ref val4)).startColor = Color32.op_Implicit(Color.white); ((EmitParams)(ref val4)).rotation = Random.Range(0f, 360f); EmitParams val5 = val4; particles.Emit(val5, 1); } } internal static void Cleanup() { if (Object.op_Implicit((Object)(object)material)) { Object.Destroy((Object)(object)material); } if (Object.op_Implicit((Object)(object)texture)) { Object.Destroy((Object)(object)texture); } material = null; texture = null; attempted = false; } } internal static class EffectRules { internal const float Duration = 120f; internal const float Interval = 15f; internal const float WarningLead = 0.7f; internal const float StaminaCost = 15f; internal const float FireDamage = 30f; internal const float Range = 4f; internal const float ConeCosine = 0.8660254f; internal static bool InCone(float distanceSquared, float forwardDot) { if (float.IsNaN(distanceSquared) || float.IsNaN(forwardDot) || distanceSquared < 0f || distanceSquared > 16f || forwardDot < 0f) { return false; } return forwardDot * forwardDot >= distanceSquared * 0.8660254f * 0.8660254f; } } internal enum BelchEvent { None, Warning, Fire } internal sealed class BelchSchedule { private float next = 15f; private bool warned; internal void Reset() { next = 15f; warned = false; } internal BelchEvent Advance(float elapsed) { if (float.IsNaN(elapsed) || elapsed < 0f || elapsed >= 120f) { return BelchEvent.None; } if (elapsed > next + 0.5f) { next = ((float)Math.Floor(elapsed / 15f) + 1f) * 15f; warned = false; } if (next >= 120f) { return BelchEvent.None; } if (elapsed >= next) { next += 15f; warned = false; return BelchEvent.Fire; } if (!warned && elapsed >= next - 0.7f) { warned = true; return BelchEvent.Warning; } return BelchEvent.None; } } [BepInPlugin("local.firebelch.mead", "Fire Belch Mead", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "local.firebelch.mead"; public const string MeadName = "MeadFireBelch"; public const string BaseName = "MeadBaseFireBelch"; public const string EffectName = "SE_FireBelch"; internal static Plugin Instance; internal static ConfigEntry<float> SoundVolume; internal static AudioClip[] Sounds; private readonly List<Object> assets = new List<Object>(); private Harmony harmony; private Sprite meadIcon; private Sprite baseIcon; private SE_FireBelch effect; internal ManualLogSource LoggerForEffects => ((BaseUnityPlugin)this).Logger; private void Awake() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown Instance = this; SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.65f, new ConfigDescription("Local sound volume, also controlled by the game's SFX volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); AddLocalization(); meadIcon = LoadIcon("mead.png"); baseIcon = LoadIcon("mead-base.png"); effect = ScriptableObject.CreateInstance<SE_FireBelch>(); assets.Add((Object)(object)effect); ((Object)effect).name = "SE_FireBelch"; ((StatusEffect)effect).m_name = "$firebelch_effect"; ((StatusEffect)effect).m_icon = LoadIcon("status.png"); ((StatusEffect)effect).m_ttl = 120f; ((StatusEffect)effect).m_hidden = false; ((StatusEffect)effect).m_startMessage = "$firebelch_started"; ((StatusEffect)effect).m_startMessageType = (MessageType)2; ((StatusEffect)effect).m_stopMessage = "$firebelch_finished"; ((StatusEffect)effect).m_stopMessageType = (MessageType)1; ((StatusEffect)effect).m_startEffects = new EffectList(); ((StatusEffect)effect).m_stopEffects = new EffectList(); if (!ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)effect, false))) { throw new InvalidOperationException("Could not register SE_FireBelch."); } if (!Application.isBatchMode) { LoadSounds(); } harmony = new Harmony("local.firebelch.mead"); harmony.PatchAll(typeof(Plugin).Assembly); PrefabManager.OnVanillaPrefabsAvailable += RegisterItems; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Fire Belch Mead 1.0.0 ready: 120s, every 15s, 30 fire damage / 4m, 15 stamina."); } private Sprite LoadIcon(string file) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Icons", file); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); assets.Add((Object)(object)val); bool flag = false; if (File.Exists(path)) { try { flag = ImageConversion.LoadImage(val, File.ReadAllBytes(path)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not load icon " + file + ": " + ex.Message)); } } if (!flag) { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FireBelchMead.Assets." + ((file == "mead-base.png") ? "mead-base.png" : "fire-belch.png")); using MemoryStream memoryStream = new MemoryStream(); if (stream == null) { throw new FileNotFoundException("Missing embedded Fire Belch icon."); } stream.CopyTo(memoryStream); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { throw new InvalidDataException("Invalid embedded icon."); } } ((Object)val).name = "FireBelch_" + file; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)val2).name = "FireBelch_" + file; assets.Add((Object)(object)val2); return val2; } private void LoadSounds() { Sounds = (AudioClip[])(object)new AudioClip[2]; for (int i = 0; i < 2; i++) { string text = ((i == 0) ? "hiccup" : "fire-burp"); string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Sounds", text + ".wav"); WaveSamples waveSamples = null; if (File.Exists(path)) { try { using Stream stream = File.OpenRead(path); waveSamples = WaveSamples.Read(stream); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read " + text + "; using synthesized sound. " + ex.Message)); } } if (waveSamples == null) { waveSamples = new WaveSamples(BelchSynthesis.Create(i == 1), 1, 44100); } AudioClip val = AudioClip.Create("FireBelch_" + text, waveSamples.Frames, waveSamples.Channels, waveSamples.SampleRate, false); assets.Add((Object)(object)val); if (!val.SetData(waveSamples.Samples, 0)) { throw new InvalidOperationException("Could not create sound " + text); } Sounds[i] = val; } } private void RegisterItems() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterItems; try { string[] array = new string[7] { "MeadPoisonResist", "MeadBasePoisonResist", "Honey", "Thistle", "SurtlingCore", "piece_MeadCauldron", "fermenter" }; foreach (string text in array) { if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(text))) { throw new InvalidOperationException("Missing vanilla prefab: " + text); } } CustomItem val = new CustomItem("MeadFireBelch", "MeadPoisonResist"); SharedData shared = val.ItemDrop.m_itemData.m_shared; shared.m_name = "$item_firebelch"; shared.m_description = "$item_firebelch_description"; shared.m_icons = (Sprite[])(object)new Sprite[1] { meadIcon }; shared.m_consumeStatusEffect = (StatusEffect)(object)effect; shared.m_maxStackSize = 10; shared.m_food = (shared.m_foodStamina = (shared.m_foodEitr = 0f)); if (!ItemManager.Instance.AddItem(val)) { throw new InvalidOperationException("Could not register MeadFireBelch"); } ItemConfig val2 = new ItemConfig { Name = "$item_firebelchbase", Description = "$item_firebelchbase_description", CraftingStation = "piece_MeadCauldron", MinStationLevel = 1, Amount = 1, Icon = baseIcon }; val2.AddRequirement("Honey", 10, 0); val2.AddRequirement("Thistle", 5, 0); val2.AddRequirement("SurtlingCore", 1, 0); if (!ItemManager.Instance.AddItem(new CustomItem("MeadBaseFireBelch", "MeadBasePoisonResist", val2))) { throw new InvalidOperationException("Could not register MeadBaseFireBelch"); } if (!ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)new FermenterConversionConfig { FromItem = "MeadBaseFireBelch", ToItem = "MeadFireBelch", Station = Fermenters.Fermenter, ProducedItems = 6 }))) { throw new InvalidOperationException("Could not register Fire Belch fermentation."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered MeadBaseFireBelch -> 6 MeadFireBelch. Recipe: Honey 10, Thistle 5, SurtlingCore 1."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Fire Belch registration failed: " + ex)); } } private void AddLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "Russian"; localization.AddTranslation(ref text, new Dictionary<string, string> { ["item_firebelch"] = "Огненная отрыжка", ["item_firebelch_description"] = "Согревает изнутри. Окружающих — снаружи. На 120 секунд: каждые 15 секунд огненный залп перед собой, 30 огненного урона в конусе на 4 м. Залп расходует 15 выносливости; перед ним — икота и дым.", ["item_firebelchbase"] = "Основа медовухи: Огненная отрыжка", ["item_firebelchbase_description"] = "10 мёда, 5 чертополоха и 1 ядро суртлинга. Требует брожения: 6 бутылок «Огненной отрыжки». Не нюхать прямо над бочкой.", ["firebelch_effect"] = "Огненная отрыжка", ["firebelch_tooltip"] = "Каждые 15 с: огненный залп вперёд.\nОгненный урон: 30; дальность: 4 м; конус: 60°.\nРасход: 15 выносливости за залп.\nПри нехватке выносливости залп пропускается.\nПоражает враждебных существ; не ранит игроков и питомцев.\nДлительность: 120 секунд.", ["firebelch_started"] = "Кажется, мёд был с огоньком…", ["firebelch_finished"] = "Пожар в животе потушен.", ["firebelch_tired"] = "Для огненной отрыжки не хватает выносливости." }); text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { ["item_firebelch"] = "Fire Belch", ["item_firebelch_description"] = "Warms you from the inside. Everyone else, from the outside. For 120 seconds: belch fire every 15 seconds, dealing 30 fire damage in a 4 m cone for 15 stamina. A hiccup and smoke warn of each burst.", ["item_firebelchbase"] = "Mead base: Fire Belch", ["item_firebelchbase_description"] = "10 honey, 5 thistle and 1 surtling core. Ferments into 6 bottles of Fire Belch. Do not sniff directly over the barrel.", ["firebelch_effect"] = "Fire Belch", ["firebelch_tooltip"] = "Belch fire forward every 15 s.\nFire damage: 30; range: 4 m; cone: 60 degrees.\nCosts 15 stamina per burst; skipped if stamina is too low.\nHits hostile creatures, excluding players and tamed animals.\nDuration: 120 seconds.", ["firebelch_started"] = "That mead had a kick…", ["firebelch_finished"] = "The fire in your belly has gone out.", ["firebelch_tired"] = "Not enough stamina to belch fire." }); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterItems; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } BelchVfx.Cleanup(); foreach (Object asset in assets) { if (Object.op_Implicit(asset)) { Object.Destroy(asset); } } Sounds = null; Instance = null; } } public sealed class SE_FireBelch : StatusEffect { private BelchSchedule schedule; public override bool CanAdd(Character character) { return character is Player; } public override void Setup(Character character) { ((StatusEffect)this).Setup(character); schedule = new BelchSchedule(); } public override void ResetTime() { ((StatusEffect)this).ResetTime(); schedule?.Reset(); } public override void UpdateStatusEffect(float dt) { ((StatusEffect)this).UpdateStatusEffect(dt); if (!Object.op_Implicit((Object)(object)base.m_character) || !base.m_character.IsOwner() || ((StatusEffect)this).IsDone() || schedule == null) { return; } BelchEvent belchEvent = schedule.Advance(base.m_time); if (belchEvent == BelchEvent.None || base.m_character.IsTeleporting() || base.m_character.InCutscene() || base.m_character.InIntro()) { return; } BelchEmitter component = ((Component)base.m_character).GetComponent<BelchEmitter>(); if (!Object.op_Implicit((Object)(object)component)) { return; } if (belchEvent == BelchEvent.Warning) { if (base.m_character.HaveStamina(15f)) { component.Broadcast(0); } } else if (base.m_character.HaveStamina(15f)) { base.m_character.UseStamina(15f); component.Fire(); } else { base.m_character.Message((MessageType)1, "$firebelch_tired", 0, (Sprite)null, false); } } public override bool IsDone() { if (!(base.m_time >= base.m_ttl)) { if (Object.op_Implicit((Object)(object)base.m_character)) { return base.m_character.IsDead(); } return false; } return true; } public override string GetTooltipString() { return Localization.instance.Localize("$firebelch_tooltip"); } public override void Stop() { schedule = null; ((StatusEffect)this).Stop(); } } internal sealed class WaveSamples { internal const int MaximumFileBytes = 16777216; internal const float MaximumDuration = 15f; internal float[] Samples { get; } internal int Channels { get; } internal int SampleRate { get; } internal int Frames => Samples.Length / Channels; internal float Duration => (float)Frames / (float)SampleRate; internal WaveSamples(float[] samples, int channels, int sampleRate) { Samples = samples; Channels = channels; SampleRate = sampleRate; } internal static WaveSamples Read(Stream stream) { if (!stream.CanRead || !stream.CanSeek || stream.Length < 44 || stream.Length > 16777216) { throw new InvalidDataException("WAV must be a readable file no larger than 16 MiB."); } stream.Position = 0L; using BinaryReader binaryReader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true); if (FourCC(binaryReader) != "RIFF") { throw new InvalidDataException("Expected RIFF WAV."); } long num = 8L + (long)binaryReader.ReadUInt32(); if (num < 44 || num > stream.Length || FourCC(binaryReader) != "WAVE") { throw new InvalidDataException("Invalid or truncated WAV header."); } bool flag = false; int num2 = 0; int num3 = 0; int num4 = 0; long num5 = -1L; uint num6 = 0u; while (stream.Position + 8 <= num) { string text = FourCC(binaryReader); uint num7 = binaryReader.ReadUInt32(); long position = stream.Position; long num8 = position + num7 + (num7 & 1); if (num8 > num) { throw new InvalidDataException("Truncated WAV chunk."); } if (text == "fmt ") { if (flag || num7 < 16) { throw new InvalidDataException("Invalid WAV format chunk."); } flag = true; ushort num9 = binaryReader.ReadUInt16(); num2 = binaryReader.ReadUInt16(); uint num10 = binaryReader.ReadUInt32(); uint num11 = binaryReader.ReadUInt32(); num4 = binaryReader.ReadUInt16(); ushort num12 = binaryReader.ReadUInt16(); if (num9 != 1 || num12 != 16 || (num2 != 1 && num2 != 2)) { throw new InvalidDataException("Export as WAV PCM 16-bit, mono or stereo."); } if (num10 < 8000 || num10 > 192000 || num4 != num2 * 2 || num11 != num10 * num4) { throw new InvalidDataException("Invalid WAV sample rate or frame size."); } num3 = (int)num10; } else if (text == "data") { if (num5 >= 0) { throw new InvalidDataException("Multiple WAV data chunks are unsupported."); } num5 = position; num6 = num7; } stream.Position = num8; } if (stream.Position != num || !flag || num5 < 0 || num6 == 0 || num6 % num4 != 0L) { throw new InvalidDataException("Missing or incomplete WAV audio data."); } if ((double)num6 / (double)num4 / (double)num3 > 15.0) { throw new InvalidDataException("Sound must be at most 15 seconds long."); } stream.Position = num5; float[] array = new float[(int)num6 / 2]; for (int i = 0; i < array.Length; i++) { array[i] = (float)binaryReader.ReadInt16() / 32768f; } return new WaveSamples(array, num2, num3); } private static string FourCC(BinaryReader reader) { return Encoding.ASCII.GetString(reader.ReadBytes(4)); } } }
BepInEx/plugins/SosalMeads/SosalMeads.dll
Decompiled 10 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SosalMeads")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyInformationalVersion("1.2.1")] [assembly: AssemblyProduct("SosalMeads")] [assembly: AssemblyTitle("SosalMeads")] [assembly: AssemblyVersion("1.2.1.0")] [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 SosalMeads { internal sealed class ArcherCharge { private float readyUntil = float.NegativeInfinity; internal static bool Procs(float roll) { return roll < 0.5f; } internal void Arm(float now) { readyUntil = now + 5f; } internal bool Consume(float now, bool bow) { if (!bow || now >= readyUntil) { return false; } readyUntil = float.NegativeInfinity; return true; } } internal sealed class ArcherShot { internal Player Owner; internal int Ticket; } public sealed class ArcherArrow : MonoBehaviour { private static readonly ConditionalWeakTable<HitData, ArcherShot> Pending = new ConditionalWeakTable<HitData, ArcherShot>(); [ThreadStatic] internal static ArcherShot Impact; internal ArcherShot Shot; internal static void Mark(HitData hit, Player owner) { if (Object.op_Implicit((Object)(object)owner)) { MeadEmitter component = ((Component)owner).GetComponent<MeadEmitter>(); if (Object.op_Implicit((Object)(object)component)) { Pending.Remove(hit); Pending.Add(hit, new ArcherShot { Owner = owner, Ticket = component.ReserveArcherShot() }); } } } internal static void Attach(Projectile projectile, HitData hit) { if (hit != null && Pending.TryGetValue(hit, out var value)) { Pending.Remove(hit); ((Component)projectile).gameObject.AddComponent<ArcherArrow>().Shot = value; } } } [HarmonyPatch(typeof(Projectile), "Setup")] internal static class ArcherProjectileSetup { private static void Postfix(Projectile __instance, HitData hitData) { ArcherArrow.Attach(__instance, hitData); } } [HarmonyPatch(typeof(Projectile), "OnHit")] internal static class ArcherProjectileImpact { private static void Prefix(Projectile __instance, out ArcherShot __state) { __state = ArcherArrow.Impact; ArcherArrow.Impact = ((Component)__instance).GetComponent<ArcherArrow>()?.Shot; } private static Exception Finalizer(Exception __exception, ArcherShot __state) { ArcherArrow.Impact = __state; return __exception; } } public sealed class ArcherHitReceiver : MonoBehaviour { internal const string Rpc = "SosalMeads_ArcherHit_1"; private static readonly MethodInfo NativeDamage = AccessTools.Method(typeof(Character), "RPC_Damage", (Type[])null, (Type[])null); private Character target; private ZNetView view; private bool registered; private void Start() { Initialize(); } internal bool Initialize() { if (registered) { return true; } target = ((Component)this).GetComponent<Character>(); view = ((Component)this).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return false; } view.Register<HitData, int>("SosalMeads_ArcherHit_1", (Action<long, HitData, int>)Receive); registered = true; return true; } internal void Send(HitData hit, int ticket) { view.InvokeRPC("SosalMeads_ArcherHit_1", new object[2] { hit, ticket }); } private void Receive(long sender, HitData hit, int ticket) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || !view.IsOwner() || hit == null || !hit.m_ranged || (int)hit.m_skill != 8) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); ZNetView val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<ZNetView>() : null); if (!Object.op_Implicit((Object)(object)val2) || !val2.IsValid() || val2.GetZDO().GetOwner() != sender) { return; } float health = target.GetHealth(); NativeDamage.Invoke(target, new object[2] { sender, hit }); if (!(target.GetHealth() >= health)) { if (!(target is Player) && !target.IsTamed() && !target.IsDead() && target.m_staggerDamageFactor > 0f && BaseAI.IsEnemy((Character)(object)val, target)) { target.Stagger(hit.m_dir); } ((Component)val).GetComponent<MeadEmitter>()?.ConfirmArcherHit(ticket, target.GetZDOID()); } } } [HarmonyPatch(typeof(Character), "Awake")] internal static class AddArcherHitReceiver { private static void Postfix(Character __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ArcherHitReceiver>())) { ((Component)__instance).gameObject.AddComponent<ArcherHitReceiver>(); } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class SendArcherHit { private static bool Prefix(Character __instance, HitData hit) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 ArcherShot impact = ArcherArrow.Impact; if (impact == null || !Object.op_Implicit((Object)(object)impact.Owner) || !((Character)impact.Owner).IsOwner() || hit == null || !hit.m_ranged || (int)hit.m_skill != 8 || (Object)(object)hit.GetAttacker() != (Object)(object)impact.Owner) { return true; } ArcherHitReceiver component = ((Component)__instance).GetComponent<ArcherHitReceiver>(); if (!Object.op_Implicit((Object)(object)component) || !component.Initialize()) { return true; } component.Send(hit, impact.Ticket); return false; } } [HarmonyPatch(typeof(Player), "ConsumeItem")] internal static class ArcherDrinkVoice { private static void Postfix(Player __instance, ItemData item, bool __result) { if (__result && ((Character)__instance).IsOwner()) { object obj; if (item == null) { obj = null; } else { StatusEffect consumeStatusEffect = item.m_shared.m_consumeStatusEffect; obj = ((consumeStatusEffect != null) ? ((Object)consumeStatusEffect).name : null); } if ((string?)obj == "SE_Sosal_archer") { ((Component)__instance).GetComponent<MeadEmitter>()?.Sound(MeadAudio.ArcherDrinkClips[Random.Range(0, MeadAudio.ArcherDrinkClips.Length)]); } } } } public sealed class SE_Mead : StatusEffect { public string Key; internal ArcherCharge Archer; public override void Setup(Character character) { ((StatusEffect)this).Setup(character); if (Key == "archer") { Archer = new ArcherCharge(); } } internal void ReadyArrow() { if (Key == "archer" && !((StatusEffect)this).IsDone()) { if (Archer == null) { Archer = new ArcherCharge(); } Archer.Arm(Time.time); base.m_character.Message((MessageType)1, "Пьяный лучник: шанс усиления 50% — 5 с", 0, (Sprite)null, false); } } public override void ModifyAttack(SkillType skill, ref HitData hit) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 if (!(Key != "archer") && !((StatusEffect)this).IsDone() && Object.op_Implicit((Object)(object)base.m_character) && base.m_character.IsOwner() && hit != null && Archer != null && Archer.Consume(Time.time, (int)skill == 8) && ArcherCharge.Procs(Random.value)) { ((DamageTypes)(ref hit.m_damage)).Modify(1.5f); HitData hit2 = hit; Character character = base.m_character; ArcherArrow.Mark(hit2, (Player)(object)((character is Player) ? character : null)); } } public override bool CanAdd(Character c) { return c is Player; } public override bool IsDone() { if (!(base.m_time >= base.m_ttl)) { if (Object.op_Implicit((Object)(object)base.m_character)) { return base.m_character.IsDead(); } return false; } return true; } public override void ModifyJump(Vector3 baseJump, ref Vector3 jump) { if (Key == "goat" && !((StatusEffect)this).IsDone()) { jump.y *= Mathf.Sqrt(2f); } } public override void ModifyJumpStaminaUsage(float baseUse, ref float use) { if (Key == "goat" && !((StatusEffect)this).IsDone()) { use *= 0.6f; } } public override void ModifyMaxCarryWeight(float baseLimit, ref float limit) { if (Key == "troll" && !((StatusEffect)this).IsDone()) { limit += 700f; } } public override void ModifySpeed(float baseSpeed, ref float speed, Character c, Vector3 dir) { if (!((StatusEffect)this).IsDone()) { if (Key == "eel" && c.IsSwimming()) { speed += baseSpeed * 2f; } if (Key == "eikthyr" && c.IsRunning() && !c.IsSwimming()) { speed += baseSpeed * 0.3f; } if (Key == "boar" && c.IsRunning() && !c.IsSwimming()) { speed += baseSpeed * 0.4f; } } } public override void ModifySwimStaminaUsage(float baseUse, ref float use) { if (Key == "eel" && !((StatusEffect)this).IsDone()) { use /= 3f; } } public override void ModifyAttackStaminaUsage(float baseUse, ref float use) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 if (!(Key == "dwarf") || ((StatusEffect)this).IsDone()) { return; } Character character = base.m_character; Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if (val != null) { ItemData currentWeapon = val.GetCurrentWeapon(); if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 12) { use *= 0.6f; } } } public override string GetTooltipString() { Mead mead = Array.Find(Plugin.Meads, (Mead x) => x.Key == Key); if (mead != null) { return mead.Details; } return ((StatusEffect)this).GetTooltipString(); } } [HarmonyPatch(typeof(Player), "Awake")] internal static class AddEmitter { private static void Postfix(Player __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<MeadEmitter>())) { ((Component)__instance).gameObject.AddComponent<MeadEmitter>(); } } } [HarmonyPatch(typeof(Player), "OnJump")] internal static class GoatVoice { private static void Postfix(Player __instance) { if (((Character)__instance).IsOwner() && Plugin.Active((Character)(object)__instance, "goat") && Random.value < 0.28f) { ((Component)__instance).GetComponent<MeadEmitter>()?.Sound(0); } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class TrollKnockback { private static void Prefix(Character __instance, HitData hit) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (hit == null || hit.m_ranged || (int)hit.m_skill == 0) { return; } Character attacker = hit.GetAttacker(); if (attacker is Player && attacker.IsOwner() && Plugin.Active(attacker, "troll") && !((Object)(object)attacker == (Object)(object)__instance)) { float pushForce = hit.m_pushForce; hit.m_pushForce = pushForce * 5f; if (hit.GetTotalDamage() > 0f && !__instance.IsDead()) { ((Component)attacker).GetComponent<MeadEmitter>()?.TrollLaugh(); } } } } [HarmonyPatch] internal static class DwarfMining { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(MineRock), "Damage", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(MineRock5), "Damage", (Type[])null, (Type[])null); } private static void Prefix(HitData hit) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if (hit == null || (int)hit.m_skill != 12) { return; } Character attacker = hit.GetAttacker(); if (attacker is Player && attacker.IsOwner() && Plugin.Active(attacker, "dwarf")) { ((DamageTypes)(ref hit.m_damage)).Modify(1.5f); if (Random.value < 0.15f) { ((Component)attacker).GetComponent<MeadEmitter>()?.Sound(2); } } } } [HarmonyPatch(typeof(Player), "UpdateDodge")] internal static class EikthyrDodge { internal struct StartState { internal bool Candidate; internal Vector3 Position; } private static void Prefix(Player __instance, float dt, float ___m_queuedDodgeTimer, out StartState __state) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) __state = new StartState { Candidate = (___m_queuedDodgeTimer > dt), Position = ((Component)__instance).transform.position }; } private static void Postfix(Player __instance, float ___m_queuedDodgeTimer, bool ___m_dodgeInvincible, StartState __state) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (__state.Candidate && ___m_queuedDodgeTimer == 0f && ___m_dodgeInvincible && ((Character)__instance).IsOwner()) { if (Plugin.Active((Character)(object)__instance, "eikthyr")) { ((Component)__instance).GetComponent<MeadEmitter>()?.QueueLightning(__state.Position); } (((Character)__instance).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Sosal_archer")) as SE_Mead)?.ReadyArrow(); } } } internal sealed class LightningVisual : MonoBehaviour { private sealed class Arc { internal LineRenderer Core; internal LineRenderer Glow; internal Vector3[] Points; internal float Phase; } private readonly List<Arc> arcs = new List<Arc>(); private readonly Random random = new Random(); private static Material material; private Light flash; private float age; private float nextFlicker; private const float Lifetime = 0.65f; internal static bool NativeAvailable => Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab("fx_eikthyr_stomp")); internal static GameObject Draw(Vector3 point) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0011: 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_002f: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown GameObject val = new GameObject("Eikthyr mead lightning"); val.transform.position = point; LightningVisual lightningVisual = val.AddComponent<LightningVisual>(); lightningVisual.AddNativeParticles(); GameObject val2 = new GameObject("Blue discharge flash"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector3.up * 0.35f; lightningVisual.flash = val2.AddComponent<Light>(); lightningVisual.flash.type = (LightType)2; lightningVisual.flash.color = new Color(0.27f, 0.64f, 1f); lightningVisual.flash.range = 5f; lightningVisual.flash.intensity = 1.8f; if (!Object.op_Implicit((Object)(object)material)) { Shader val3 = ((IEnumerable<Shader>)Resources.FindObjectsOfTypeAll<Shader>()).FirstOrDefault((Func<Shader, bool>)((Shader s) => ((Object)s).name == "Sprites/Default" && s.isSupported)) ?? Shader.Find("Sprites/Default"); if (Object.op_Implicit((Object)(object)val3)) { material = new Material(val3); Plugin.Assets.Add((Object)(object)material); } } if (Object.op_Implicit((Object)(object)material)) { lightningVisual.BuildArcs(); } Object.Destroy((Object)(object)val, 1.1f); return val; } private void AddNativeParticles() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = PrefabManager.Instance.GetPrefab("fx_eikthyr_stomp"); if (!Object.op_Implicit((Object)(object)prefab)) { return; } string[] array = new string[3] { "lightning", "shockwave_plane", "shockwave" }; foreach (string text in array) { Transform val = prefab.transform.Find(text); if (!Object.op_Implicit((Object)(object)val)) { continue; } GameObject val2 = new GameObject("Native Eikthyr " + text); val2.SetActive(false); val2.transform.SetParent(((Component)this).transform, false); val2.transform.localPosition = Vector3.up * 0.1f; GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, val2.transform, false); MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren<MonoBehaviour>(true); for (int j = 0; j < componentsInChildren.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren[j]); } Collider[] componentsInChildren2 = val3.GetComponentsInChildren<Collider>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[j]); } float num = ((text == "lightning") ? 0.4f : ((text == "shockwave_plane") ? 0.17f : 0.25f)); val3.transform.localScale = Vector3.one * num; ParticleSystem[] componentsInChildren3 = val3.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem obj in componentsInChildren3) { obj.Stop(true, (ParticleSystemStopBehavior)0); MainModule main = obj.main; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).playOnAwake = false; if (text == "lightning") { ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.25f, 0.4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(18f); } else { ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.55f); } } val3.SetActive(true); val2.SetActive(true); componentsInChildren3 = val3.GetComponentsInChildren<ParticleSystem>(true); for (int j = 0; j < componentsInChildren3.Length; j++) { componentsInChildren3[j].Play(false); } } } private Vector3 Ground(Vector3 p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0065: 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) RaycastHit val = default(RaycastHit); if (Physics.Raycast(p + Vector3.up * 1.5f, Vector3.down, ref val, 4f, LayerMask.GetMask(new string[3] { "terrain", "piece", "static_solid" }), (QueryTriggerInteraction)1)) { p.y = ((RaycastHit)(ref val)).point.y + 0.06f; } return p; } private void BuildArcs() { //IL_007d: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 6; i++) { float num = (float)i * MathF.PI / 3f + Range(-0.22f, 0.22f); float num2 = Range(2.1f, 2.85f); Vector3[] array = (Vector3[])(object)new Vector3[12]; for (int j = 0; j < array.Length; j++) { float num3 = (float)j / (float)(array.Length - 1); float num4 = num + ((j == 0) ? 0f : Range(-0.13f, 0.13f)); array[j] = Ground(((Component)this).transform.position + new Vector3(Mathf.Cos(num4) * num2 * num3, 0f, Mathf.Sin(num4) * num2 * num3)); array[j].y += Mathf.Sin(num3 * MathF.PI) * Range(0.08f, 0.32f); } AddArc(array, Range(0f, 6f)); int num5 = 5; Vector3[] array2 = (Vector3[])(object)new Vector3[6]; float num6 = num + ((i % 2 == 0) ? 0.7f : (-0.7f)); for (int k = 0; k < array2.Length; k++) { float num7 = (float)k * 0.18f; array2[k] = Ground(array[num5] + new Vector3(Mathf.Cos(num6) * num7, 0f, Mathf.Sin(num6) * num7)); array2[k].y += 0.05f; } AddArc(array2, Range(0f, 6f)); } } private float Range(float a, float b) { return a + (b - a) * (float)random.NextDouble(); } private void AddArc(Vector3[] points, float phase) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Arc arc = new Arc { Points = points, Phase = phase }; arc.Glow = Line("blue halo", points, 0.095f, 0.013f, new Color(0.1f, 0.42f, 1f, 0.24f)); arc.Core = Line("white electric core", points, 0.022f, 0.0035f, new Color(0.82f, 0.95f, 1f, 0.96f)); arcs.Add(arc); } private LineRenderer Line(string name, Vector3[] points, float start, float end, Color color) { //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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(((Component)this).transform, false); LineRenderer obj = val.AddComponent<LineRenderer>(); ((Renderer)obj).sharedMaterial = material; obj.useWorldSpace = true; obj.positionCount = points.Length; obj.SetPositions(points); obj.startWidth = start; obj.endWidth = end; obj.startColor = color; obj.endColor = color; obj.numCornerVertices = 1; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } private void Update() { //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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) age += Time.deltaTime; float num = Mathf.Clamp01(1f - age / 0.65f); if (Object.op_Implicit((Object)(object)flash)) { flash.intensity = 1.8f * num * num; } if (age < nextFlicker) { return; } nextFlicker = age + 0.045f; foreach (Arc arc in arcs) { float num2 = num * ((Mathf.Sin(age * 79f + arc.Phase) > 0.05f) ? 1f : 0.13f); LineRenderer core = arc.Core; Color startColor = (arc.Core.endColor = new Color(0.82f, 0.95f, 1f, num2)); core.startColor = startColor; LineRenderer glow = arc.Glow; startColor = (arc.Glow.endColor = new Color(0.1f, 0.42f, 1f, num2 * 0.24f)); glow.startColor = startColor; for (int i = 1; i < arc.Points.Length - 1; i++) { Vector3 val3 = arc.Points[i] + new Vector3(Range(-0.065f, 0.065f), Range(0f, 0.075f), Range(-0.065f, 0.065f)); arc.Core.SetPosition(i, val3); arc.Glow.SetPosition(i, val3); } } } } internal static class MeadAudio { internal static AudioClip[] Clips; internal static readonly int[] ArcherDrinkClips = new int[5] { 5, 6, 7, 8, 18 }; internal static readonly int[] ArcherHitClips = new int[5] { 9, 10, 11, 16, 17 }; internal const int BoarSound = 19; internal static AudioClip BoarClip { get { GameObject prefab = PrefabManager.Instance.GetPrefab("sfx_boar_alerted"); if (Object.op_Implicit((Object)(object)prefab)) { ZSFX[] componentsInChildren = prefab.GetComponentsInChildren<ZSFX>(true); foreach (ZSFX val in componentsInChildren) { if (val.m_audioClips != null && val.m_audioClips.Length != 0 && Object.op_Implicit((Object)(object)val.m_audioClips[0])) { return val.m_audioClips[0]; } } } return null; } } internal static AudioClip LightningClip { get { GameObject prefab = PrefabManager.Instance.GetPrefab("fx_eikthyr_stomp"); if (Object.op_Implicit((Object)(object)prefab)) { ZSFX[] componentsInChildren = prefab.GetComponentsInChildren<ZSFX>(true); foreach (ZSFX val in componentsInChildren) { if (((Object)val).name == "sfx_shockwave (1)" && val.m_audioClips.Length != 0 && Object.op_Implicit((Object)(object)val.m_audioClips[0])) { return val.m_audioClips[0]; } } } return null; } } internal static bool IsTrollVoice(int kind) { if (kind >= 12) { return kind < 16; } return false; } internal static void Load() { string[] array = new string[19] { "goat", "troll", "dwarf", "lightning", "archer_hiccup", "archer_drink0", "archer_drink1", "archer_drink2", "archer_drink3", "archer_hit0", "archer_hit1", "archer_hit2", "troll_laugh0", "troll_laugh1", "troll_laugh2", "troll_laugh3", "archer_hit3", "archer_hit4", "archer_drink4" }; Clips = (AudioClip[])(object)new AudioClip[array.Length]; for (int i = 0; i < array.Length; i++) { using BinaryReader binaryReader = new BinaryReader(new MemoryStream(Plugin.ReadAsset(array[i] + ".wav"))); binaryReader.ReadBytes(12); int num = 1; int num2 = 22050; byte[] array2 = null; while (binaryReader.BaseStream.Position + 8 <= binaryReader.BaseStream.Length) { string text = new string(binaryReader.ReadChars(4)); int num3 = binaryReader.ReadInt32(); long position = binaryReader.BaseStream.Position + num3 + (num3 & 1); if (text == "fmt ") { if (binaryReader.ReadInt16() != 1) { throw new InvalidDataException("PCM required"); } num = binaryReader.ReadInt16(); num2 = binaryReader.ReadInt32(); binaryReader.ReadInt32(); binaryReader.ReadInt16(); if (binaryReader.ReadInt16() != 16) { throw new InvalidDataException("16 bit required"); } } else if (text == "data") { array2 = binaryReader.ReadBytes(num3); } binaryReader.BaseStream.Position = position; } if (array2 == null) { throw new InvalidDataException(array[i]); } float[] array3 = new float[array2.Length / 2]; for (int j = 0; j < array3.Length; j++) { array3[j] = (float)(short)(array2[j * 2] | (array2[j * 2 + 1] << 8)) / 32768f; } AudioClip val = AudioClip.Create("Sosal_" + array[i], array3.Length / num, num, num2, false); val.SetData(array3, 0); Clips[i] = val; Plugin.Assets.Add((Object)(object)val); } } } public sealed class MeadEmitter : MonoBehaviour { private const string Rpc = "SosalMeads_Event_1"; private const string ArcherConfirmRpc = "SosalMeads_ArcherConfirm_1"; private ZNetView view; private Player player; private bool registered; private float nextLightning = -1f; private float fireAt = -1f; private Vector3 origin; private readonly float[] nextSend = new float[20]; private readonly float[] nextReceive = new float[20]; private static readonly float[] Intervals = new float[20] { 5f, 1.7f, 9f, 2.9f, 0.25f, 0.5f, 0.5f, 0.5f, 0.5f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.5f, 10f }; private bool wasBoarRunning; private float nextTrollRoll; private float nextTrollReceive; private readonly Dictionary<int, float> archerShots = new Dictionary<int, float>(); private int archerSequence; private void Start() { Initialize(); } private bool Initialize() { if (registered) { return true; } player = ((Component)this).GetComponent<Player>(); view = ((Component)this).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return false; } view.Register<int, Vector3>("SosalMeads_Event_1", (Action<long, int, Vector3>)Receive); view.Register<int, ZDOID>("SosalMeads_ArcherConfirm_1", (Action<long, int, ZDOID>)ReceiveArcherHit); registered = true; return true; } internal int ReserveArcherShot() { List<int> list = new List<int>(); foreach (KeyValuePair<int, float> archerShot in archerShots) { if (Time.time >= archerShot.Value) { list.Add(archerShot.Key); } } foreach (int item in list) { archerShots.Remove(item); } int num = ++archerSequence; archerShots[num] = Time.time + 60f; return num; } internal void ConfirmArcherHit(int ticket, ZDOID target) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (Initialize()) { view.InvokeRPC("SosalMeads_ArcherConfirm_1", new object[2] { ticket, target }); } } private void ReceiveArcherHit(long sender, int ticket, ZDOID target) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)view) && view.IsValid() && view.IsOwner() && archerShots.TryGetValue(ticket, out var value) && !(Time.time >= value)) { ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(target) : null); if (val != null && val.GetOwner() == sender) { archerShots.Remove(ticket); Sound(MeadAudio.ArcherHitClips[Random.Range(0, MeadAudio.ArcherHitClips.Length)]); } } } internal void TrollLaugh() { if (Initialize() && view.IsOwner() && !(Time.time < nextTrollRoll)) { nextTrollRoll = Time.time + 0.25f; if (!(Random.value >= 0.5f)) { int num = Random.Range(12, 16); nextTrollRoll = Time.time + ((MeadAudio.Clips != null) ? (MeadAudio.Clips[num].length + 0.15f) : 2f); Sound(num); } } } internal void Sound(int kind) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (kind >= 0 && kind < Intervals.Length && kind != 3 && Initialize() && view.IsOwner() && !(Time.time < nextSend[kind])) { nextSend[kind] = Time.time + Intervals[kind]; view.InvokeRPC(ZNetView.Everybody, "SosalMeads_Event_1", new object[2] { kind, ((Character)player).GetCenterPoint() }); } } internal void QueueLightning(Vector3 position) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (Initialize() && view.IsOwner() && !(Time.time < nextLightning) && !(fireAt >= 0f)) { nextLightning = Time.time + 3f; origin = position; fireAt = Time.time + 0.5f; } } private void Update() { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024a: 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_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown if (!registered) { Initialize(); return; } if (Object.op_Implicit((Object)(object)view) && view.IsValid() && view.IsOwner()) { bool flag = Plugin.Active((Character)(object)player, "boar") && ((Character)player).IsRunning() && !((Character)player).IsSwimming() && !((Character)player).IsTeleporting() && !((Character)player).InCutscene() && !((Character)player).InIntro(); if (flag && !wasBoarRunning) { Sound(19); } wasBoarRunning = flag; } if (fireAt < 0f || Time.time < fireAt) { return; } fireAt = -1f; if (!view.IsOwner() || !Plugin.Active((Character)(object)player, "eikthyr") || ((Character)player).IsTeleporting() || ((Character)player).InCutscene() || ((Character)player).InIntro()) { return; } Vector3 val = ((Component)player).transform.position - origin; if (((Vector3)(ref val)).sqrMagnitude > 144f) { return; } view.InvokeRPC(ZNetView.Everybody, "SosalMeads_Event_1", new object[2] { 3, origin }); Character[] array = Character.GetAllCharacters().ToArray(); foreach (Character val2 in array) { if (!Object.op_Implicit((Object)(object)val2) || val2 is Player || val2.IsDead() || val2.IsTamed() || !BaseAI.IsEnemy((Character)(object)player, val2)) { continue; } CapsuleCollider collider = val2.GetCollider(); if (Object.op_Implicit((Object)(object)collider) && ((Collider)collider).enabled) { Vector3 val3 = origin + Vector3.up * 0.15f; Vector3 val4 = ((Collider)collider).ClosestPoint(val3); Vector3 delta = val4 - val3; if (!(((Vector3)(ref delta)).sqrMagnitude > 9f) && !Blocked(val3, delta)) { HitData val5 = new HitData { m_point = val4, m_dir = ((Vector3)(ref delta)).normalized, m_hitCollider = (Collider)(object)collider, m_blockable = true, m_dodgeable = true, m_skill = (SkillType)0 }; val5.m_damage.m_lightning = 30f; val5.SetAttacker((Character)(object)player); val2.Damage(val5); } } } } private static bool Blocked(Vector3 from, Vector3 delta) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref delta)).magnitude < 0.01f) { return false; } RaycastHit[] array = Physics.RaycastAll(from, ((Vector3)(ref delta)).normalized, ((Vector3)(ref delta)).magnitude, -5, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>())) { return true; } } return false; } private void Receive(long sender, int kind, Vector3 position) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)view) || !view.IsValid() || sender != view.GetZDO().GetOwner() || kind < 0 || kind >= Intervals.Length || !Object.op_Implicit((Object)(object)player) || ((Character)player).IsDead() || Application.isBatchMode || float.IsNaN(position.x) || float.IsNaN(position.y) || float.IsNaN(position.z) || float.IsInfinity(position.x) || float.IsInfinity(position.y) || float.IsInfinity(position.z)) { return; } Vector3 val = position - ((Component)player).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 225f || Time.unscaledTime < nextReceive[kind] || (MeadAudio.IsTrollVoice(kind) && Time.unscaledTime < nextTrollReceive)) { return; } nextReceive[kind] = Time.unscaledTime + Intervals[kind]; if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { val = position - ((Component)Player.m_localPlayer).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 1600f) { return; } } GameObject val2 = new GameObject("Sosal mead sound"); val2.transform.position = position; if (kind >= 4) { val2.transform.SetParent(((Component)player).transform, true); } AudioClip val3 = (AudioClip)(kind switch { 19 => MeadAudio.BoarClip, 3 => MeadAudio.LightningClip, _ => (MeadAudio.Clips != null) ? MeadAudio.Clips[kind] : null, }); if (MeadAudio.IsTrollVoice(kind)) { nextTrollReceive = Time.unscaledTime + (Object.op_Implicit((Object)(object)val3) ? (val3.length + 0.1f) : 2f); } if (Object.op_Implicit((Object)(object)val3)) { AudioSource val4 = val2.AddComponent<AudioSource>(); val4.playOnAwake = false; val4.clip = val3; val4.spatialBlend = 1f; val4.dopplerLevel = 0f; val4.minDistance = 2f; val4.maxDistance = 22f; val4.rolloffMode = (AudioRolloffMode)1; bool flag = false; if (Object.op_Implicit((Object)(object)AudioMan.instance) && Object.op_Implicit((Object)(object)AudioMan.instance.m_masterMixer)) { AudioMixerGroup[] array = AudioMan.instance.m_masterMixer.FindMatchingGroups("SFX"); if (array.Length != 0) { val4.outputAudioMixerGroup = array[0]; flag = true; } } val4.volume = Plugin.Volume.Value * (flag ? 1f : AudioMan.GetSFXVolume()); val4.Play(); } if (kind == 3) { LightningVisual.Draw(position); } Object.Destroy((Object)(object)val2, Object.op_Implicit((Object)(object)val3) ? Mathf.Max(2f, val3.length + 0.2f) : 2f); } } [Serializable] internal sealed class ModelData { public string name; public PartData[] parts; } [Serializable] internal sealed class PartData { public string name; public string kind; public float[] positions; public float[] normals; public float[] uvs; public float[] color; public float roughness = 0.72f; public float metallic; public bool textured; } internal sealed class PreparedPart { internal string Name; internal Mesh Mesh; internal Material Material; } internal static class ModelVisual { private static readonly Dictionary<string, PreparedPart[]> Cache = new Dictionary<string, PreparedPart[]>(); private static readonly HashSet<int> Prefabs = new HashSet<int>(); private static Texture2D grain; private static Shader shader; private static Shader glassShader; internal static bool GlassProbePassed; internal static int Applied => Prefabs.Count; private static void Transparent(Material mat) { mat.SetOverrideTag("RenderType", "Transparent"); if (mat.HasProperty("_Mode")) { mat.SetFloat("_Mode", 3f); } mat.SetInt("_SrcBlend", 1); mat.SetInt("_DstBlend", 10); mat.SetInt("_ZWrite", 0); mat.DisableKeyword("_ALPHATEST_ON"); mat.DisableKeyword("_ALPHABLEND_ON"); mat.EnableKeyword("_ALPHAPREMULTIPLY_ON"); mat.renderQueue = 3000; } private static Shader SelectGlassShader(Shader[] loaded) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) Shader[] array = loaded.Where((Shader s) => ((Object)s).name == "Standard" && s.isSupported).ToArray(); if ((int)SystemInfo.graphicsDeviceType == 4) { return array.FirstOrDefault(); } GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Sosal glass probe"; val.layer = 31; Object.DestroyImmediate((Object)(object)val.GetComponent<Collider>()); val.transform.position = new Vector3(20000f, 20000f, 20000f); val.transform.localScale = Vector3.one * 0.2f; GameObject val2 = new GameObject("Sosal glass probe camera"); Camera val3 = val2.AddComponent<Camera>(); ((Behaviour)val3).enabled = false; ((Component)val3).transform.position = val.transform.position + Vector3.forward; ((Component)val3).transform.LookAt(val.transform); val3.cullingMask = int.MinValue; val3.orthographic = true; val3.orthographicSize = 0.2f; val3.nearClipPlane = 0.01f; val3.farClipPlane = 2f; val3.clearFlags = (CameraClearFlags)2; val3.backgroundColor = Color.red; val3.allowHDR = false; val3.allowMSAA = false; GameObject val4 = new GameObject("Sosal glass probe light"); Light obj = val4.AddComponent<Light>(); obj.type = (LightType)1; obj.intensity = 0.8f; obj.cullingMask = int.MinValue; ((Component)obj).transform.rotation = Quaternion.Euler(25f, 180f, 0f); RenderTexture val5 = (val3.targetTexture = new RenderTexture(16, 16, 16)); RenderTexture active = RenderTexture.active; Texture2D val7 = new Texture2D(16, 16, (TextureFormat)3, false); Shader result = null; int num = 0; try { Shader[] array2 = array; foreach (Shader val8 in array2) { Material val9 = new Material(val8) { color = new Color(0.02f, 0.08f, 0.7f, 1f) }; val9.SetFloat("_Glossiness", 0.1f); val9.SetFloat("_Metallic", 0f); ((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = val9; val3.Render(); RenderTexture.active = val5; val7.ReadPixels(new Rect(0f, 0f, 16f, 16f), 0, 0); val7.Apply(); float r = val7.GetPixel(8, 8).r; val9.color = new Color(0.02f, 0.08f, 0.7f, 0.1f); Transparent(val9); val3.Render(); RenderTexture.active = val5; val7.ReadPixels(new Rect(0f, 0f, 16f, 16f), 0, 0); val7.Apply(); float r2 = val7.GetPixel(8, 8).r; num++; Object.DestroyImmediate((Object)(object)val9); if (r < 0.4f && r2 > 0.65f && r2 - r > 0.35f) { result = val8; GlassProbePassed = true; break; } } } finally { val3.targetTexture = null; RenderTexture.active = active; val5.Release(); Object[] array3 = (Object[])(object)new Object[5] { (Object)val5, (Object)val7, (Object)val, (Object)val2, (Object)val4 }; for (int num2 = 0; num2 < array3.Length; num2++) { Object.DestroyImmediate(array3[num2]); } } Plugin.Log("Glass pixel probe: " + (GlassProbePassed ? "PASS" : "FAIL") + "; tested " + num + " of " + array.Length + " same-name shaders"); return result; } internal static void Apply(GameObject prefab, string key) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0245: 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_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)prefab) || Object.op_Implicit((Object)(object)prefab.transform.Find("attach/Sosal3D"))) { return; } PreparedPart[] array = Load(key); LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } MonoBehaviour[] componentsInChildren3 = prefab.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren3) { if (Object.op_Implicit((Object)(object)val) && ((object)val).GetType().Name.IndexOf("Billboard", StringComparison.OrdinalIgnoreCase) >= 0) { Object.DestroyImmediate((Object)(object)val); } } Transform val2 = prefab.transform.Find("attach"); if (!Object.op_Implicit((Object)(object)val2)) { val2 = new GameObject("attach").transform; val2.SetParent(prefab.transform, false); } ((Component)val2).gameObject.SetActive(true); val2.localPosition = Vector3.zero; val2.localRotation = Quaternion.identity; val2.localScale = Vector3.one; GameObject val3 = new GameObject("Sosal3D"); val3.transform.SetParent(val2, false); val3.layer = prefab.layer; Bounds val4 = default(Bounds); bool flag = true; PreparedPart[] array2 = array; foreach (PreparedPart preparedPart in array2) { GameObject val5 = new GameObject(preparedPart.Name); val5.transform.SetParent(val3.transform, false); val5.layer = prefab.layer; val5.AddComponent<MeshFilter>().sharedMesh = preparedPart.Mesh; MeshRenderer val6 = val5.AddComponent<MeshRenderer>(); ((Renderer)val6).sharedMaterial = preparedPart.Material; if (preparedPart.Material.renderQueue >= 3000) { ((Renderer)val6).shadowCastingMode = (ShadowCastingMode)0; } if (flag) { val4 = preparedPart.Mesh.bounds; flag = false; } else { ((Bounds)(ref val4)).Encapsulate(preparedPart.Mesh.bounds); } } Collider[] componentsInChildren4 = prefab.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } BoxCollider obj = prefab.AddComponent<BoxCollider>(); obj.center = ((Bounds)(ref val4)).center; obj.size = ((Bounds)(ref val4)).size; switch (key) { case "eel": case "archer": case "boar": { Light[] componentsInChildren5 = prefab.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { ((Behaviour)componentsInChildren5[i]).enabled = false; } break; } } switch (key) { case "troll": case "eikthyr": case "surtling": case "dwarf": { Light[] componentsInChildren5 = prefab.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { componentsInChildren5[i].color = (Color)(key switch { "surtling" => new Color(1f, 0.055f, 0.015f), "eikthyr" => new Color(0.24f, 0.62f, 1f), "troll" => new Color(0.16f, 0.45f, 1f), _ => new Color(1f, 0.78f, 0.07f), }); } break; } } Prefabs.Add(((Object)prefab).GetInstanceID()); } private static PreparedPart[] Load(string key) { //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Expected O, but got Unknown //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Expected O, but got Unknown if (Cache.TryGetValue(key, out var value)) { return value; } if (!Object.op_Implicit((Object)(object)grain)) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); if (Environment.GetCommandLineArgs().Contains("-sosal-selftest")) { StringBuilder stringBuilder = new StringBuilder(); foreach (Shader item in array.OrderBy((Shader s) => ((Object)s).name)) { stringBuilder.AppendLine(((Object)item).name + " supported=" + item.isSupported); for (int num = 0; num < item.GetPropertyCount(); num++) { stringBuilder.Append(item.GetPropertyName(num) + " "); } stringBuilder.AppendLine(); } File.WriteAllText(Path.Combine(Application.persistentDataPath, "SosalMeads-shaders.txt"), stringBuilder.ToString()); } glassShader = SelectGlassShader(array); shader = glassShader ?? ((IEnumerable<Shader>)array).FirstOrDefault((Func<Shader, bool>)((Shader s) => ((Object)s).name == "Custom/Creature")); if (!Object.op_Implicit((Object)(object)shader)) { throw new InvalidOperationException("No compatible lit shader for 3D mead models"); } if (!Object.op_Implicit((Object)(object)glassShader)) { throw new InvalidOperationException("No transparent glass shader for 3D mead models"); } grain = new Texture2D(2, 2, (TextureFormat)4, true); ((Texture)grain).filterMode = (FilterMode)0; ((Texture)grain).wrapMode = (TextureWrapMode)0; ImageConversion.LoadImage(grain, Plugin.ReadAsset("surface_grain.png"), true); Plugin.Assets.Add((Object)(object)grain); Plugin.Log("3D models use shader " + ((Object)shader).name + "; glass: " + ((Object)glassShader).name); } ModelData modelData = JsonConvert.DeserializeObject<ModelData>(Encoding.UTF8.GetString(Plugin.ReadAsset(key + ".mesh.json"))); if (modelData?.parts == null || modelData.parts.Length == 0) { throw new InvalidOperationException("Empty model data: " + key); } List<PreparedPart> list = new List<PreparedPart>(); PartData[] parts = modelData.parts; foreach (PartData partData in parts) { int num3 = partData.positions.Length / 3; Vector3[] array2 = (Vector3[])(object)new Vector3[num3]; Vector3[] array3 = (Vector3[])(object)new Vector3[num3]; Vector2[] array4 = (Vector2[])(object)new Vector2[num3]; Color[] array5 = (Color[])(object)new Color[num3]; int[] array6 = new int[num3]; for (int num4 = 0; num4 < num3; num4++) { array2[num4] = new Vector3(partData.positions[num4 * 3], partData.positions[num4 * 3 + 1], partData.positions[num4 * 3 + 2]); array3[num4] = new Vector3(partData.normals[num4 * 3], partData.normals[num4 * 3 + 1], partData.normals[num4 * 3 + 2]); array4[num4] = ((partData.uvs != null) ? new Vector2(partData.uvs[num4 * 2], partData.uvs[num4 * 2 + 1]) : new Vector2(Mathf.Atan2(array2[num4].z, array2[num4].x) / (MathF.PI * 2f), array2[num4].y * 4f)); array5[num4] = Color.white; array6[num4] = num4; } Mesh val = new Mesh { name = "Sosal_" + key + "_" + partData.name }; val.vertices = array2; val.normals = array3; val.uv = array4; val.colors = array5; val.triangles = array6; val.RecalculateBounds(); bool num5 = partData.kind == "glass"; Material val2 = new Material(num5 ? glassShader : shader) { name = "Sosal_" + key + "_" + partData.name, color = new Color(partData.color[0], partData.color[1], partData.color[2], (partData.color.Length > 3) ? partData.color[3] : 1f) }; if (partData.textured) { val2.mainTexture = (Texture)(object)grain; } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", partData.metallic); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", 1f - partData.roughness); } if (val2.HasProperty("_Cutoff")) { val2.SetFloat("_Cutoff", 0f); } if (num5) { Transparent(val2); val2.renderQueue = 3000 + (partData.name.Contains("lip") ? 1 : 0); } Plugin.Assets.Add((Object)(object)val); Plugin.Assets.Add((Object)(object)val2); list.Add(new PreparedPart { Name = partData.name, Mesh = val, Material = val2 }); } return Cache[key] = list.ToArray(); } } internal sealed class Mead { internal string Key; internal string Id; internal string Name; internal string Flavor; internal string Stats; internal int Duration; internal int Yield; internal KeyValuePair<string, int>[] Recipe; internal string BaseId => "MeadBase" + Id.Substring(4); internal string EffectId => "SE_Sosal_" + Key; internal int Hash => StringExtensionMethods.GetStableHashCode(EffectId); internal string Details => "Длительность: " + Duration + " с.\n" + Stats; internal string Description => Details + "\n\n" + Flavor; internal string BaseDescription => "Требует брожения. Выход: " + Yield + " бут.\n\nЭффект готового напитка:\n" + Details; internal Mead(string key, string id, string name, int duration, int yield, string flavor, string stats, params object[] recipe) { Key = key; Id = id; Name = name; Duration = duration; Yield = yield; Flavor = flavor; Stats = stats; Recipe = (from i in Enumerable.Range(0, recipe.Length / 2) select new KeyValuePair<string, int>((string)recipe[i * 2], (int)recipe[i * 2 + 1])).ToArray(); } } [BepInPlugin("local.sosal.meadcollection", "Sosal Mead Collection", "1.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "local.sosal.meadcollection"; internal static Plugin Instance; internal static ConfigEntry<float> Volume; internal static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>(); internal static readonly Dictionary<string, SE_Mead> Effects = new Dictionary<string, SE_Mead>(); internal static readonly Dictionary<string, string> Visuals = new Dictionary<string, string>(); internal static readonly List<Object> Assets = new List<Object>(); internal static readonly Mead[] Meads = new Mead[7] { new Mead("goat", "MeadGoatSpryness", "Козья прыть", 120, 6, "Ноги помнят горные тропы. Горло — прежнего хозяина.", "Прыжки в 2 раза выше (+100%).\nРасход выносливости на прыжок: −40%.\nИногда при прыжке вырывается козье блеяние.", "Honey", 10, "MushroomYellow", 4, "HareMeat", 2, "Blueberries", 3), new Mead("troll", "MeadTrollKiss", "Поцелуй тролля", 320, 3, "Тролль проявил нежность. Противник отлетел на несколько метров.", "Удары в ближнем бою отбрасывают в 5 раз сильнее.\nПереносимый вес: +700.\nПри ударе — 50% шанс случайного хохота. Звуки не накладываются друг на друга.", "Honey", 10, "Blueberries", 5, "Thistle", 1, "TrollHide", 5, "BoneFragments", 5), new Mead("eel", "MeadEelPants", "Угорь в штанах", 240, 3, "На суше — викинг. В воде — скользкая неприятность.", "Плавание в 3 раза быстрее.\nРасход выносливости при плавании в 3 раза меньше.", "Honey", 5, "FishRaw", 3, "MushroomYellow", 2, "SerpentScale", 1), new Mead("eikthyr", "MeadEikthyrHeels", "Пятки Эйктюра", 180, 3, "Копыт ещё нет. Гром уже есть.", "Скорость бега: +30%.\nПосле переката в месте отталкивания через 0,5 с бьёт молния.\nУрон врагам: 30 молнией в радиусе 3 м.\nРазряд срабатывает не чаще раза в 3 с.", "Honey", 10, "HardAntler", 1, "TrophyDeer", 1, "Dandelion", 3), new Mead("dwarf", "MeadDwarfGreed", "Жадность дворфа", 500, 3, "Ещё одну жилу — и точно домой.", "Урон киркой по руде и камню: +50%.\nРасход выносливости на удары киркой: −40%.", "Honey", 10, "MushroomYellow", 4, "CopperOre", 2, "Coins", 10), new Mead("archer", "MeadDrunkenArcher", "Пьяный лучник", 180, 2, "Трезвым я бы так не попал", "После переката следующий выстрел из лука в течение 5 с с шансом 50% наносит на 50% больше урона.\nПри срабатывании усиления попадание ошеломляет врага, как при парировании, если он подвержен этому эффекту.\nБонус расходуется при выстреле и не накапливается.\nПосле питья — случайная реплика; при усиленном попадании — икота и довольный возглас.\nЗвуки слышны окружающим.", "Honey", 10, "Cloudberry", 10, "MushroomYellow", 7, "Root", 1), new Mead("boar", "MeadBoarRush", "Кабанья поступь", 120, 3, "Тормоза придумали олени", "Скорость бега: +40%.\nРасход выносливости обычный.\nПри начале спринта — кабанье хрюканье, слышное окружающим, не чаще раза в 10 с.", "Honey", 8, "Carrot", 5, "TrophyBoar", 1, "HareMeat", 1) }; internal static readonly Mead[] LegacyMeads = new Mead[2] { new Mead("matvey", "MeadMatvey", "Пердящий Матвей", 100, 6, "Матвей уверял, что это нормальный осадок.", "Скорость передвижения: −30%.\nПериодически выпускает газы с громким звуком.\nНа земле залпы кратко толкают тебя вперёд."), new Mead("surtling", "MeadFireBelch", "Дыхание суртлинга", 120, 6, "Согревает изнутри. Окружающих — снаружи.", "Каждые 15 с выпускает огненный залп перед собой.\nУрон: 30 огнём; дальность: 4 м.\nРасход: 15 выносливости за залп.\nПри нехватке выносливости залп пропускается.") }; private Harmony harmony; private void Awake() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Expected O, but got Unknown //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Expected O, but got Unknown //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Expected O, but got Unknown Instance = this; Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.55f, new ConfigDescription("Volume of the new mead sounds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); string[] array = new string[9] { "matvey", "surtling", "goat", "troll", "eel", "eikthyr", "dwarf", "archer", "boar" }; foreach (string text in array) { string[] array2 = new string[3] { "", "_base", "_status" }; foreach (string text2 in array2) { Icons[text + text2] = LoadIcon(text + text2); } } Dictionary<string, string> dictionary = new Dictionary<string, string>(); Mead[] meads = Meads; foreach (Mead mead in meads) { dictionary["sosal_" + mead.Key] = mead.Name; dictionary["sosal_" + mead.Key + "_base"] = "Основа медовухи: " + mead.Name; dictionary["sosal_" + mead.Key + "_description"] = mead.Description; dictionary["sosal_" + mead.Key + "_base_description"] = mead.BaseDescription; SE_Mead sE_Mead = ScriptableObject.CreateInstance<SE_Mead>(); ((Object)sE_Mead).name = mead.EffectId; sE_Mead.Key = mead.Key; ((StatusEffect)sE_Mead).m_name = "$sosal_" + mead.Key; ((StatusEffect)sE_Mead).m_icon = Icons[mead.Key + "_status"]; ((StatusEffect)sE_Mead).m_ttl = mead.Duration; ((StatusEffect)sE_Mead).m_startEffects = new EffectList(); ((StatusEffect)sE_Mead).m_stopEffects = new EffectList(); ((StatusEffect)sE_Mead).m_hidden = false; Assets.Add((Object)(object)sE_Mead); Effects[mead.Key] = sE_Mead; if (!ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)sE_Mead, false))) { throw new InvalidOperationException("Status registration: " + mead.EffectId); } } meads = LegacyMeads; foreach (Mead mead2 in meads) { dictionary["sosal_" + mead2.Key + "_description"] = mead2.Description; dictionary["sosal_" + mead2.Key + "_base_description"] = mead2.BaseDescription; } dictionary["item_firebelch"] = "Дыхание суртлинга"; dictionary["item_firebelchbase"] = "Основа медовухи: Дыхание суртлинга"; dictionary["firebelch_effect"] = "Дыхание суртлинга"; dictionary["item_firebelchbase_description"] = "10 мёда, 5 чертополоха и 1 ядро суртлинга. Требует брожения: 6 бутылок «Дыхания суртлинга». Не нюхать прямо над бочкой."; dictionary["firebelch_tired"] = "Для «Дыхания суртлинга» не хватает выносливости."; array = new string[2] { "Russian", "English" }; for (int i = 0; i < array.Length; i++) { string text3 = array[i]; LocalizationManager.Instance.GetLocalization().AddTranslation(ref text3, dictionary); } Visuals["MeadMatvey"] = "matvey"; Visuals["MeadBaseMatvey"] = "matvey_base"; Visuals["MeadFireBelch"] = "surtling"; Visuals["MeadBaseFireBelch"] = "surtling_base"; meads = Meads; foreach (Mead mead3 in meads) { Visuals[mead3.Id] = mead3.Key; Visuals[mead3.BaseId] = mead3.Key + "_base"; } harmony = new Harmony("local.sosal.meadcollection"); harmony.PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += Register; ItemManager.OnItemsRegistered += RefreshExisting; ItemManager.OnItemsRegisteredFejd += RefreshExisting; if (!Application.isBatchMode) { MeadAudio.Load(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"SosalMeads ready: 7 new meads; 18 real mesh models; Boar Rush and networked voices."); } internal static byte[] ReadAsset(string name) { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("SosalMeads.Assets." + name); using MemoryStream memoryStream = new MemoryStream(); if (stream == null) { throw new FileNotFoundException(name); } stream.CopyTo(memoryStream); return memoryStream.ToArray(); } private static Sprite LoadIcon(string key) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Object)val).name = "Sosal_" + key; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; if (!ImageConversion.LoadImage(val, ReadAsset(key + ".png"), true)) { throw new InvalidDataException(key); } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); Assets.Add((Object)(object)val); Assets.Add((Object)(object)val2); return val2; } private void Register() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= Register; Mead[] meads = Meads; foreach (Mead mead in meads) { try { KeyValuePair<string, int>[] recipe = mead.Recipe; for (int j = 0; j < recipe.Length; j++) { KeyValuePair<string, int> keyValuePair = recipe[j]; if (!Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(keyValuePair.Key))) { throw new InvalidOperationException("Missing ingredient " + keyValuePair.Key); } } CustomItem val = new CustomItem(mead.Id, "MeadPoisonResist"); SharedData shared = val.ItemDrop.m_itemData.m_shared; shared.m_name = "$sosal_" + mead.Key; shared.m_description = "$sosal_" + mead.Key + "_description"; shared.m_icons = (Sprite[])(object)new Sprite[1] { Icons[mead.Key] }; shared.m_food = (shared.m_foodStamina = (shared.m_foodEitr = 0f)); shared.m_maxStackSize = 10; shared.m_consumeStatusEffect = (StatusEffect)(object)Effects[mead.Key]; ModelVisual.Apply(val.ItemPrefab, mead.Key); if (!ItemManager.Instance.AddItem(val)) { throw new InvalidOperationException("AddItem " + mead.Id); } ItemConfig val2 = new ItemConfig { Name = "$sosal_" + mead.Key + "_base", Description = "$sosal_" + mead.Key + "_base_description", CraftingStation = "piece_MeadCauldron", MinStationLevel = 1, Amount = 1, Icon = Icons[mead.Key + "_base"] }; recipe = mead.Recipe; for (int j = 0; j < recipe.Length; j++) { KeyValuePair<string, int> keyValuePair2 = recipe[j]; val2.AddRequirement(keyValuePair2.Key, keyValuePair2.Value, 0); } CustomItem val3 = new CustomItem(mead.BaseId, "MeadBasePoisonResist", val2); ModelVisual.Apply(val3.ItemPrefab, mead.Key + "_base"); if (!ItemManager.Instance.AddItem(val3)) { throw new InvalidOperationException("AddItem " + mead.BaseId); } if (!ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)new FermenterConversionConfig { FromItem = mead.BaseId, ToItem = mead.Id, Station = Fermenters.Fermenter, ProducedItems = mead.Yield }))) { throw new InvalidOperationException("Fermentation " + mead.Id); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered " + mead.BaseId + " -> " + mead.Yield + " " + mead.Id + "; duration " + mead.Duration + "s")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Mead registration FAILED: " + mead.Id + " " + ex)); } } try { RefreshExisting(); } finally { if (Environment.GetCommandLineArgs().Contains("-sosal-selftest")) { ((MonoBehaviour)this).StartCoroutine(SelfTest.Run()); } } } private static void RefreshExisting() { foreach (KeyValuePair<string, string> visual in Visuals) { CustomItem item = ItemManager.Instance.GetItem(visual.Key); if (item != null) { SharedData shared = item.ItemDrop.m_itemData.m_shared; shared.m_icons = (Sprite[])(object)new Sprite[1] { Icons[visual.Value] }; shared.m_description = "$sosal_" + visual.Value + "_description"; if (!visual.Value.EndsWith("_base") && Object.op_Implicit((Object)(object)shared.m_consumeStatusEffect)) { shared.m_consumeStatusEffect.m_icon = Icons[visual.Value + "_status"]; } ModelVisual.Apply(item.ItemPrefab, visual.Value); } } ((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Visuals verified: " + ModelVisual.Applied + " prefabs with real 3D meshes.")); } internal static bool Active(Character c, string key) { if (Object.op_Implicit((Object)(object)c) && !c.IsDead()) { return c.GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Sosal_" + key)); } return false; } internal static void Log(string message) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } PrefabManager.OnVanillaPrefabsAvailable -= Register; ItemManager.OnItemsRegistered -= RefreshExisting; ItemManager.OnItemsRegisteredFejd -= RefreshExisting; } } internal static class SelfTest { internal static IEnumerator Run() { yield return null; string path = Path.Combine(Application.persistentDataPath, "SosalMeads-selftest-result.txt"); File.WriteAllText(path, DateTime.UtcNow.ToString("O") + " RUNNING"); try { if ((int)SystemInfo.graphicsDeviceType != 4) { Require(ModelVisual.GlassProbePassed, "glass pixel transparency check"); } foreach (KeyValuePair<string, string> visual in Plugin.Visuals) { CustomItem item = ItemManager.Instance.GetItem(visual.Key); Require(item != null, "missing item " + visual.Key); Require(Object.op_Implicit((Object)(object)item.ItemPrefab.transform.Find("attach/Sosal3D")), "missing model " + visual.Key); Require(item.ItemPrefab.GetComponentsInChildren<MeshFilter>(true).Any((MeshFilter x) => Object.op_Implicit((Object)(object)x.sharedMesh) && x.sharedMesh.vertexCount > 30), "no mesh " + visual.Key); Require(Object.op_Implicit((Object)(object)item.ItemDrop.m_itemData.m_shared.m_icons[0]), "no icon " + visual.Key); BoxCollider component = item.ItemPrefab.GetComponent<BoxCollider>(); Require(Object.op_Implicit((Object)(object)component) && ((Collider)component).enabled, "no collider " + visual.Key); if (visual.Value.EndsWith("_base")) { continue; } Transform obj = item.ItemPrefab.transform.Find("attach/Sosal3D"); Material sharedMaterial = ((Renderer)((Component)obj.Find("glass_shell")).GetComponent<MeshRenderer>()).sharedMaterial; Require(sharedMaterial.renderQueue >= 3000 && sharedMaterial.color.a < 0.5f, "opaque glass " + visual.Key); Require(sharedMaterial.shader.isSupported, "unsupported glass shader " + visual.Key); Require(Object.op_Implicit((Object)(object)obj.Find("liquid_with_meniscus")), "missing separate liquid " + visual.Key); if (visual.Value == "eel" || visual.Value == "archer" || visual.Value == "boar") { Require(item.ItemPrefab.GetComponentsInChildren<Light>(true).All((Light x) => !((Behaviour)x).enabled), visual.Value + " must not glow"); } if (new string[4] { "troll", "eikthyr", "surtling", "dwarf" }.Contains(visual.Value)) { Light[] componentsInChildren = item.ItemPrefab.GetComponentsInChildren<Light>(true); Require(componentsInChildren.Length != 0, "missing bottle light " + visual.Key); Light[] array = componentsInChildren; for (int num = 0; num < array.Length; num++) { Color color = array[num].color; Require((visual.Value == "surtling") ? (color.r > 0.9f && color.g < 0.1f) : ((visual.Value == "dwarf") ? (color.r > 0.9f && color.g > 0.7f && color.b < 0.1f) : (color.b > 0.9f && color.b > color.g && color.g > color.r)), "bottle light colour " + visual.Key); } } } SE_Mead sE_Mead = Plugin.Effects["goat"]; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(2f, 10f, 3f); ((StatusEffect)sE_Mead).ModifyJump(val, ref val); Require((double)Math.Abs(val.y * val.y / 100f - 2f) < 0.0001 && val.x == 2f && val.z == 3f, "jump height"); float num2 = 20f; ((StatusEffect)sE_Mead).ModifyJumpStaminaUsage(20f, ref num2); Require((double)Math.Abs(num2 - 12f) < 0.0001, "jump stamina"); KeyValuePair<string, int>[] recipe = Plugin.Meads.Single((Mead x) => x.Key == "goat").Recipe; Require(recipe.Any((KeyValuePair<string, int> x) => x.Key == "HareMeat" && x.Value == 2) && !recipe.Any((KeyValuePair<string, int> x) => x.Key == "Entrails"), "goat hare recipe"); Require(Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab("HareMeat")), "missing raw hare meat prefab"); Require(LightningVisual.NativeAvailable, "missing native Eikthyr stomp visual"); Require(Object.op_Implicit((Object)(object)MeadAudio.LightningClip), "missing native Eikthyr sound"); float num3 = 300f; ((StatusEffect)Plugin.Effects["troll"]).ModifyMaxCarryWeight(300f, ref num3); Require(num3 == 1000f, "carry weight"); num2 = 9f; ((StatusEffect)Plugin.Effects["eel"]).ModifySwimStaminaUsage(9f, ref num2); Require(num2 == 3f, "swim stamina"); Require(Plugin.Meads.Single((Mead x) => x.Key == "eikthyr").Yield == 3, "Eikthyr yield"); Require(((StatusEffect)Plugin.Effects["dwarf"]).m_ttl == 500f, "dwarf duration"); Mead mead = Plugin.Meads.Single((Mead x) => x.Key == "boar"); Require(mead.Duration == 120 && mead.Yield == 3 && mead.Recipe.Length == 4 && mead.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "Honey" && x.Value == 8) && mead.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "Carrot" && x.Value == 5) && mead.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "TrophyBoar" && x.Value == 1) && mead.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "HareMeat" && x.Value == 1), "boar recipe and duration/yield"); num2 = 12f; ((StatusEffect)Plugin.Effects["boar"]).ModifyRunStaminaDrain(12f, ref num2, Vector3.forward); Require(num2 == 12f, "boar leaves running stamina unchanged"); Require(Object.op_Implicit((Object)(object)MeadAudio.BoarClip), "missing native boar snort"); Character component2 = PrefabManager.Instance.GetPrefab("Boar").GetComponent<Character>(); FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_running"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Character), "m_swimTimer"); object value = fieldInfo.GetValue(component2); object value2 = fieldInfo2.GetValue(component2); try { fieldInfo.SetValue(component2, true); fieldInfo2.SetValue(component2, 1f); float num4 = 10f; ((StatusEffect)Plugin.Effects["boar"]).ModifySpeed(10f, ref num4, component2, Vector3.forward); Require((double)Math.Abs(num4 - 14f) < 0.0001, "boar running speed +40 percent"); fieldInfo.SetValue(component2, false); num4 = 10f; ((StatusEffect)Plugin.Effects["boar"]).ModifySpeed(10f, ref num4, component2, Vector3.forward); Require(num4 == 10f, "boar does not boost walking"); fieldInfo.SetValue(component2, true); fieldInfo2.SetValue(component2, 0f); num4 = 10f; ((StatusEffect)Plugin.Effects["boar"]).ModifySpeed(10f, ref num4, component2, Vector3.forward); Require(num4 == 10f, "boar does not boost swimming"); } finally { fieldInfo.SetValue(component2, value); fieldInfo2.SetValue(component2, value2); } Mead mead2 = Plugin.Meads.Single((Mead x) => x.Key == "archer"); Require(mead2.Duration == 180 && mead2.Yield == 2 && mead2.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "Root" && x.Value == 1) && mead2.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "Cloudberry" && x.Value == 10) && mead2.Recipe.Any((KeyValuePair<string, int> x) => x.Key == "MushroomYellow" && x.Value == 7), "archer recipe and duration/yield"); ArcherCharge archerCharge = new ArcherCharge(); Require(!archerCharge.Consume(10f, bow: true), "archer must dodge first"); archerCharge.Arm(10f); Require(!archerCharge.Consume(11f, bow: false) && archerCharge.Consume(14.999f, bow: true) && !archerCharge.Consume(14.999f, bow: true), "archer bow only / exactly one shot"); archerCharge.Arm(20f); Require(!archerCharge.Consume(25f, bow: true), "archer five second expiry"); archerCharge.Arm(30f); archerCharge.Arm(31f); Require(archerCharge.Consume(35.9f, bow: true) && !archerCharge.Consume(35.9f, bow: true), "archer refresh does not stack"); Require(ArcherCharge.Procs(0.4999f) && !ArcherCharge.Procs(0.5f), "archer 50 percent proc threshold"); string text = Path.Combine(Application.persistentDataPath, "SosalMeads-selftest"); Directory.CreateDirectory(text); if ((int)SystemInfo.graphicsDeviceType != 4) { foreach (string item2 in Plugin.Visuals.Values.Distinct()) { Render(item2, text); } RenderLightning(text); Plugin.Log("SELFTEST rendered 18 models to " + text); } Plugin.Log("SELFTEST PASS: 18 prefabs/models/icons/colliders; 9 transparent shells and static liquid meshes; numeric effects; archer charge/chance; boar recipe, unchanged stamina and native audio."); File.WriteAllText(path, DateTime.UtcNow.ToString("O") + " PASS: 18 models/items/icons/colliders; glass pixel probe; 9 static liquid meshes; numeric effects; archer charge/chance; boar recipe/stamina/audio; unlit archer, eel and boar; native Eikthyr particles/audio."); } catch (Exception ex) { Plugin.Log("SELFTEST FAIL: " + ex); File.WriteAllText(path, DateTime.UtcNow.ToString("O") + " FAIL: " + ex); } yield return null; Application.Quit(); } private static void Require(bool ok, string message) { if (!ok) { throw new InvalidOperationException(message); } } private static void RenderLightning(string directory) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(15000f, 15000f, 15000f); GameObject val2 = LightningVisual.Draw(val); Require(val2.GetComponentsInChildren<ParticleSystem>().Length >= 3, "missing native lightning particles"); Require(val2.GetComponentsInChildren<Aoe>().Length == 0 && val2.GetComponentsInChildren<ZNetView>().Length == 0, "visual must not add damage or network objects"); Transform[] componentsInChildren = val2.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 31; } GameObject val3 = new GameObject("Lightning preview camera"); Camera val4 = val3.AddComponent<Camera>(); ((Behaviour)val4).enabled = false; val4.cullingMask = int.MinValue; ((Component)val4).transform.position = val + new Vector3(5f, 6f, 7f); ((Component)val4).transform.LookAt(val); val4.fieldOfView = 46f; val4.nearClipPlane = 0.1f; val4.farClipPlane = 30f; val4.clearFlags = (CameraClearFlags)2; val4.backgroundColor = new Color(0.025f, 0.055f, 0.07f, 1f); RenderTexture val5 = new RenderTexture(640, 480, 24); RenderTexture active = RenderTexture.active; val4.targetTexture = val5; Texture2D val6 = new Texture2D(640, 480, (TextureFormat)3, false); float[] array = new float[3] { 0.08f, 0.2f, 0.4f }; foreach (float num in array) { ParticleSystem[] componentsInChildren2 = val2.GetComponentsInChildren<ParticleSystem>(); for (int j = 0; j < componentsInChildren2.Length; j++) { componentsInChildren2[j].Simulate(num, false, true, true); } val4.Render(); RenderTexture.active = val5; val6.ReadPixels(new Rect(0f, 0f, 640f, 480f), 0, 0); val6.Apply(); File.WriteAllBytes(Path.Combine(directory, "eikthyr-lightning-" + Mathf.RoundToInt(num * 100f) + ".png"), ImageConversion.EncodeToPNG(val6)); } val4.targetTexture = null; RenderTexture.active = active; val5.Release(); Object[] array2 = (Object[])(object)new Object[4] { (Object)val6, (Object)val5, (Object)val3, (Object)val2 }; for (int i = 0; i < array2.Length; i++) { Object.DestroyImmediate(array2[i]); } } private static void Render(string key, string directory) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown GameObject val = new GameObject("Sosal selftest " + key); ModelVisual.Apply(val, key); val.transform.position = new Vector3(10000f, 10000f, 10000f); Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 31; } GameObject val2 = new GameObject("Sosal preview camera"); Camera obj = val2.AddComponent<Camera>(); obj.cullingMask = int.MinValue; bool flag = key.EndsWith("_base"); ((Component)obj).transform.position = val.transform.position + (flag ? new Vector3(0.31f, 0.33f, 0.43f) : new Vector3(0.32f, 0.23f, 0.52f)); ((Component)obj).transform.LookAt(val.transform.position + Vector3.up * (flag ? 0.04f : 0.14f)); obj.fieldOfView = 32f; obj.nearClipPlane = 0.01f; obj.farClipPlane = 3f; obj.clearFlags = (CameraClearFlags)2; obj.backgroundColor = new Color(0.1f, 0.12f, 0.14f, 1f); GameObject val3 = new GameObject("Sosal preview light"); Light obj2 = val3.AddComponent<Light>(); obj2.type = (LightType)1; obj2.intensity = 1.25f; obj2.cullingMask = int.MinValue; ((Component)obj2).transform.rotation = Quaternion.Euler(35f, 150f, 0f); RenderTexture val4 = new RenderTexture(512, 512, 24); RenderTexture active = RenderTexture.active; obj.targetTexture = val4; obj.Render(); RenderTexture.active = val4; Texture2D val5 = new Texture2D(512, 512, (TextureFormat)3, false); val5.ReadPixels(new Rect(0f, 0f, 512f, 512f), 0, 0); val5.Apply(); File.WriteAllBytes(Path.Combine(directory, key + ".png"), ImageConversion.EncodeToPNG(val5)); obj.targetTexture = null; RenderTexture.active = active; Object.DestroyImmediate((Object)(object)val5); val4.Release(); Object.DestroyImmediate((Object)(object)val4); Object.DestroyImmediate((Object)(object)val); Object.DestroyImmediate((Object)val2); Object.DestroyImmediate((Object)(object)val3); } } }