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 FireSalts v0.1.1
BepInEx/plugins/FireSalts/FireSalts.dll
Decompiled 12 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("FireSalts.RuntimeProbe")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FireSalts")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.1.0")] [assembly: AssemblyInformationalVersion("0.1.1")] [assembly: AssemblyProduct("FireSalts")] [assembly: AssemblyTitle("FireSalts")] [assembly: AssemblyVersion("0.1.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 FireSalts { internal sealed class FireRuntime : MonoBehaviour { internal static readonly List<FireRuntime> Live = new List<FireRuntime>(); private static readonly List<FireRuntime> nearest = new List<FireRuntime>(); private static readonly Collider[] overlaps = (Collider[])(object)new Collider[32]; private static readonly HashSet<ItemDrop> visited = new HashSet<ItemDrop>(); private static int cursor; internal Fireplace Fire; internal ZNetView View; internal string Prefab; internal FireVisual Visual; private bool selected; private float distance; internal bool Valid { get { if ((Object)(object)Fire != (Object)null && (Object)(object)View != (Object)null) { return View.IsValid(); } return false; } } internal bool Burning { get { if (Valid) { return Fire.IsBurning(); } return false; } } internal Vector3 Center => ((Component)this).transform.TransformPoint(Vector3.up * ((Prefab == "bonfire") ? 1.1f : 0.5f)); internal static void Attach(Fireplace fire) { ZNetView component = ((Component)fire).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || (Object)(object)((Component)fire).GetComponent<FireRuntime>() != (Object)null) { return; } string text = null; string[] array = new string[3] { "fire_pit", "hearth", "bonfire" }; foreach (string text2 in array) { if (component.GetZDO().GetPrefab() == StringExtensionMethods.GetStableHashCode(text2)) { text = text2; } } if (text != null) { FireRuntime fireRuntime = ((Component)fire).gameObject.AddComponent<FireRuntime>(); fireRuntime.Fire = fire; fireRuntime.View = component; fireRuntime.Prefab = text; Live.Add(fireRuntime); } } private void OnDestroy() { Restore(); Live.Remove(this); } private void OnDisable() { Restore(); } internal bool Active(long now, out int salt, out long start) { salt = 0; start = 0L; if (Valid) { return Rules.TryState(View.GetZDO().GetString("smeagsmods.firesalts.state.v1", ""), now, out salt, out start); } return false; } internal bool Contains(Vector3 world) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0019: 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) Vector3 val = ((Component)this).transform.InverseTransformPoint(world); return Rules.InVolume(Prefab, val.x, val.y, val.z); } internal static void TickAuthority() { if (!Plugin.Running || (Object)(object)ZNet.instance == (Object)null || Live.Count == 0) { return; } long now = Plugin.Now; int num = Math.Min(Live.Count, 16); for (int i = 0; i < num; i++) { if (cursor >= Live.Count) { cursor = 0; } FireRuntime fireRuntime = Live[cursor++]; if ((Object)(object)fireRuntime != (Object)null && fireRuntime.Valid && fireRuntime.View.IsOwner()) { fireRuntime.Scan(now); } } } private void Scan(long now) { //IL_00ca: 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_00d6: 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_009e: 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) //IL_010f: 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_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) ZDO zdo = View.GetZDO(); int salt; long start; bool flag = Active(now, out salt, out start); bool burning = Burning; if ((!flag || !burning) && zdo.GetString("smeagsmods.firesalts.state.v1", "").Length > 0) { zdo.Set("smeagsmods.firesalts.state.v1", ""); } if (!burning || flag) { return; } Vector3 val = ((Prefab == "bonfire") ? new Vector3(1.2f, 1.4f, 1.2f) : ((Prefab == "hearth") ? new Vector3(0.85f, 0.7f, 1.4f) : new Vector3(0.8f, 0.65f, 0.8f))); int num = Physics.OverlapBoxNonAlloc(((Component)this).transform.TransformPoint(Vector3.up * ((Prefab == "bonfire") ? 1.5f : 0.65f)), val, overlaps, ((Component)this).transform.rotation, LayerMask.GetMask(new string[1] { "item" }), (QueryTriggerInteraction)1); visited.Clear(); for (int i = 0; i < num; i++) { Collider val2 = overlaps[i]; overlaps[i] = null; if ((Object)(object)val2 == (Object)null || (Object)(object)val2.attachedRigidbody == (Object)null) { continue; } ItemDrop component = ((Component)val2.attachedRigidbody).GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || !visited.Add(component)) { continue; } Salt salt2 = Salts.Get(component); ZNetView component2 = ((Component)component).GetComponent<ZNetView>(); if (salt2 == null || (Object)(object)component2 == (Object)null || !component2.IsValid() || !Contains(((Component)component).transform.position)) { continue; } ZDO data = component2.GetZDO(); long num2 = data.GetLong("smeagsmods.firesalts.armed.v1", 0L); if (!Rules.IsArmed(num2, now) || (Object)(object)NearestContaining(((Component)component).transform.position) != (Object)(object)this) { continue; } if (!component2.IsOwner()) { component.RequestOwn(); continue; } component.Load(); if (Rules.CanConsume(View.IsOwner(), component2.IsOwner(), Burning, Active(now, out salt, out start), Contains(((Component)component).transform.position), component.m_itemData.m_stack, salt2.Id, data.GetLong("smeagsmods.firesalts.armed.v1", 0L), now) && component.CanPickup(true) && Reaction.Apply(salt2.Id, now, num2, (Action<long>)delegate(long value) { data.Set("smeagsmods.firesalts.armed.v1", value); }, (Func<bool>)component.RemoveOne, (Action<string>)delegate(string state) { zdo.Set("smeagsmods.firesalts.state.v1", state); })) { Plugin.Log("Consumed one " + salt2.Prefab + " at " + Prefab + "; shared deadline " + Rules.Expiry(now, 30)); break; } } } private static FireRuntime NearestContaining(Vector3 position) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) FireRuntime fireRuntime = null; float num = float.MaxValue; foreach (FireRuntime item in Live) { if (!((Object)(object)item == (Object)null) && item.Burning && item.Contains(position)) { Vector3 val = item.Center - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num || (sqrMagnitude == num && (Object)(object)fireRuntime != (Object)null && string.CompareOrdinal(((object)Unsafe.As<ZDOID, ZDOID>(ref item.View.GetZDO().m_uid)/*cast due to .constrained prefix*/).ToString(), ((object)Unsafe.As<ZDOID, ZDOID>(ref fireRuntime.View.GetZDO().m_uid)/*cast due to .constrained prefix*/).ToString()) < 0)) { fireRuntime = item; num = sqrMagnitude; } } } return fireRuntime; } internal static void SelectVisuals() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) nearest.Clear(); Player localPlayer = Player.m_localPlayer; bool flag = Plugin.Running && Plugin.Instance.Visuals.Value && (Object)(object)localPlayer != (Object)null; long now = Plugin.Now; foreach (FireRuntime item in Live) { item.selected = false; if (flag && item.Burning && item.Active(now, out var _, out var _)) { Vector3 val = item.Center - ((Component)localPlayer).transform.position; item.distance = ((Vector3)(ref val)).sqrMagnitude; if (item.distance <= 1024f) { nearest.Add(item); } } } nearest.Sort((FireRuntime a, FireRuntime b) => a.distance.CompareTo(b.distance)); for (int num = 0; num < Math.Min(nearest.Count, 8); num++) { nearest[num].selected = true; } foreach (FireRuntime item2 in Live) { if (!item2.selected) { item2.Restore(); } } } internal static void TickVisuals() { long now = Plugin.Now; foreach (FireRuntime item in Live) { if (!item.selected || !Plugin.Running || !Plugin.Instance.Visuals.Value || !item.Burning || !item.Active(now, out var salt, out var start)) { item.Restore(); continue; } if (item.Visual == null) { item.Visual = new FireVisual(item); } item.Visual.Tick(salt, start, now); } } internal void Restore() { Visual?.Dispose(); Visual = null; } internal static void RestoreAll() { foreach (FireRuntime item in Live) { if ((Object)(object)item != (Object)null) { item.Restore(); } } } internal static void DetachAll() { RestoreAll(); FireRuntime[] array = Live.ToArray(); foreach (FireRuntime fireRuntime in array) { if ((Object)(object)fireRuntime != (Object)null) { Object.Destroy((Object)(object)fireRuntime); } } Live.Clear(); nearest.Clear(); cursor = 0; FireVisual.DisposeShared(); } } internal sealed class FireVisual : IDisposable { private sealed class ParticleSnapshot { internal ParticleSystem System; internal MinMaxGradient Start; internal MinMaxGradient Lifetime; internal bool LifetimeEnabled; internal ParticleSystemRenderer Renderer; internal MaterialPropertyBlock Properties; } private sealed class LightSnapshot { internal Light Light; internal Color Color; } private readonly FireRuntime fire; private readonly List<ParticleSnapshot> particles = new List<ParticleSnapshot>(); private readonly List<LightSnapshot> lights = new List<LightSnapshot>(); private GameObject effects; private ParticleSystem sparks; private AudioSource sound; private static AudioClip pop; private static AudioClip crackle; private int lastSalt; private int lastPulse; private long lastStart; internal FireVisual(FireRuntime fire) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //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_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_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0183: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) this.fire = fire; HashSet<GameObject> hashSet = new HashSet<GameObject>(); if ((Object)(object)fire.Fire.m_enabledObject != (Object)null) { hashSet.Add(fire.Fire.m_enabledObject); } if ((Object)(object)fire.Fire.m_enabledObjectHigh != (Object)null) { hashSet.Add(fire.Fire.m_enabledObjectHigh); } if ((Object)(object)fire.Fire.m_enabledObjectLow != (Object)null) { hashSet.Add(fire.Fire.m_enabledObjectLow); } HashSet<ParticleSystem> hashSet2 = new HashSet<ParticleSystem>(); HashSet<Light> hashSet3 = new HashSet<Light>(); foreach (GameObject item in hashSet) { ParticleSystem[] componentsInChildren = item.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { string text = ((Object)val).name.ToLowerInvariant(); if (!text.Contains("smok") && (text.Contains("flame") || text.Contains("flare") || text.Contains("spar")) && hashSet2.Add(val)) { ParticleSystemRenderer component = ((Component)val).GetComponent<ParticleSystemRenderer>(); MaterialPropertyBlock val2 = new MaterialPropertyBlock(); if ((Object)(object)component != (Object)null) { ((Renderer)component).GetPropertyBlock(val2); } List<ParticleSnapshot> list = particles; ParticleSnapshot obj = new ParticleSnapshot { System = val }; MainModule main = val.main; obj.Start = ((MainModule)(ref main)).startColor; ColorOverLifetimeModule colorOverLifetime = val.colorOverLifetime; obj.Lifetime = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color; colorOverLifetime = val.colorOverLifetime; obj.LifetimeEnabled = ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled; obj.Renderer = component; obj.Properties = val2; list.Add(obj); } } Light[] componentsInChildren2 = item.GetComponentsInChildren<Light>(true); foreach (Light val3 in componentsInChildren2) { if (hashSet3.Add(val3)) { lights.Add(new LightSnapshot { Light = val3, Color = val3.color }); } } } CreateAccents(); } private void CreateAccents() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_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_00be: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_011d: 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_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_0145: 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_015a: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_018f: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) effects = new GameObject("FireSalts_DecorativeAccents"); effects.transform.SetParent(((Component)fire).transform, false); effects.transform.localPosition = Vector3.up * ((fire.Prefab == "bonfire") ? 1.2f : 0.35f); effects.SetActive(false); sparks = effects.AddComponent<ParticleSystem>(); MainModule main = sparks.main; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).duration = 30f; ((MainModule)(ref main)).maxParticles = 24; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.7f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1.5f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.035f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.7f); ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = sparks.emission; ((EmissionModule)(ref emission)).enabled = false; ShapeModule shape = sparks.shape; ((ShapeModule)(ref shape)).enabled = false; CollisionModule collision = sparks.collision; ((CollisionModule)(ref collision)).enabled = false; SubEmittersModule subEmitters = sparks.subEmitters; ((SubEmittersModule)(ref subEmitters)).enabled = false; LightsModule val = sparks.lights; ((LightsModule)(ref val)).enabled = false; ColorOverLifetimeModule colorOverLifetime = sparks.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val2 = new Gradient(); val2.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val2); ParticleSystemRenderer component = ((Component)sparks).GetComponent<ParticleSystemRenderer>(); component.renderMode = (ParticleSystemRenderMode)0; Material val3 = null; foreach (ParticleSnapshot particle in particles) { if (((Object)particle.System).name.ToLowerInvariant().Contains("spar") && (Object)(object)particle.Renderer != (Object)null) { val3 = ((Renderer)particle.Renderer).sharedMaterial; break; } } if ((Object)(object)val3 == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab("bonfire"); if ((Object)(object)prefab != (Object)null) { ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val4 in componentsInChildren) { if (((Object)val4).name == "Sparks") { ParticleSystemRenderer component2 = ((Component)val4).GetComponent<ParticleSystemRenderer>(); val3 = ((component2 != null) ? ((Renderer)component2).sharedMaterial : null); break; } } } } ((Renderer)component).sharedMaterial = val3; ((Renderer)component).enabled = (Object)(object)val3 != (Object)null; if ((Object)(object)pop == (Object)null) { pop = MakeSound("FireSalts_OriginalPop", isCrackle: false); } if ((Object)(object)crackle == (Object)null) { crackle = MakeSound("FireSalts_OriginalCrackle", isCrackle: true); } sound = effects.AddComponent<AudioSource>(); sound.playOnAwake = false; sound.loop = false; sound.spatialBlend = 1f; sound.volume = 0.12f; sound.minDistance = 1f; sound.maxDistance = 12f; sound.rolloffMode = (AudioRolloffMode)1; sound.dopplerLevel = 0f; sound.priority = 180; effects.SetActive(true); sparks.Play(false); } private static AudioClip MakeSound(string name, bool isCrackle) { float[] array = new float[isCrackle ? 3840 : 1920]; Random random = new Random(isCrackle ? 671 : 193); float num = 0f; for (int i = 0; i < array.Length; i++) { double num2 = (double)i / 24000.0; float num3 = (float)(random.NextDouble() * 2.0 - 1.0); num = num * 0.45f + num3 * 0.55f; double num4 = Math.Exp((0.0 - num2) * (double)(isCrackle ? 32 : 75)); num4 = ((!isCrackle) ? (num4 * Math.Min(1.0, (double)i / 20.0)) : (num4 * (0.3 + 0.7 * Math.Pow(Math.Sin(num2 * 190.0), 8.0)))); array[i] = (float)((double)num * num4 * 0.6); } AudioClip obj = AudioClip.Create(name, array.Length, 1, 24000, false); obj.SetData(array, 0); return obj; } internal void Tick(int saltId, long start, long now) { //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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0087: 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_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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //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_0145: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) Color color = Salts.Get(saltId).Color; if (saltId != lastSalt || start != lastStart) { lastSalt = saltId; lastStart = start; lastPulse = Rules.Pulse(now, start) - ((now - start < 5000000) ? 1 : 0); foreach (ParticleSnapshot particle in particles) { if ((Object)(object)particle.System == (Object)null) { continue; } MainModule main = particle.System.main; ((MainModule)(ref main)).startColor = Tint(particle.Start, color); ColorOverLifetimeModule colorOverLifetime = particle.System.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = Tint(particle.Lifetime, Color.white); ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = particle.LifetimeEnabled; if (!((Object)(object)particle.Renderer != (Object)null) || !((Object)(object)((Renderer)particle.Renderer).sharedMaterial != (Object)null)) { continue; } MaterialPropertyBlock val = new MaterialPropertyBlock(); ((Renderer)particle.Renderer).GetPropertyBlock(val); string[] array = new string[2] { "_TintColor", "_Color" }; foreach (string text in array) { Material sharedMaterial = ((Renderer)particle.Renderer).sharedMaterial; if (sharedMaterial.HasProperty(text)) { Color color2 = sharedMaterial.GetColor(text); float num = Mathf.Max(color2.r, Mathf.Max(color2.g, color2.b)); val.SetColor(text, new Color(num, num, num, color2.a)); } } ((Renderer)particle.Renderer).SetPropertyBlock(val); } } foreach (LightSnapshot light in lights) { if ((Object)(object)light.Light != (Object)null) { light.Light.color = Recolor(light.Color, color); } } if (!Plugin.Instance.Sound.Value && (Object)(object)sound != (Object)null) { sound.Stop(); } int num2 = Rules.Pulse(now, start); if (num2 <= lastPulse) { return; } lastPulse = num2; for (int j = 0; j < 5; j++) { float num3 = (float)(num2 * 73 + j * 137) * (MathF.PI / 180f); EmitParams val2 = default(EmitParams); ((EmitParams)(ref val2)).position = effects.transform.position; ((EmitParams)(ref val2)).velocity = new Vector3(Mathf.Cos(num3) * 0.6f, 1.3f + (float)(j % 3) * 0.3f, Mathf.Sin(num3) * 0.6f); ((EmitParams)(ref val2)).startColor = Color32.op_Implicit(color); ((EmitParams)(ref val2)).startLifetime = 0.7f; ((EmitParams)(ref val2)).startSize = 0.035f; EmitParams val3 = val2; sparks.Emit(val3, 1); } if (Plugin.Instance.Sound.Value && (Object)(object)Player.m_localPlayer != (Object)null) { Vector3 val4 = ((Component)Player.m_localPlayer).transform.position - fire.Center; if (((Vector3)(ref val4)).sqrMagnitude <= 144f) { sound.PlayOneShot((num2 % 3 == 0) ? pop : crackle); } } } private static MinMaxGradient Tint(MinMaxGradient original, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) ParticleSystemGradientMode mode = ((MinMaxGradient)(ref original)).mode; switch (mode - 1) { case 0: case 3: { MinMaxGradient result = default(MinMaxGradient); ((MinMaxGradient)(ref result))..ctor(TintGradient(((MinMaxGradient)(ref original)).gradient, color)); ((MinMaxGradient)(ref result)).mode = ((MinMaxGradient)(ref original)).mode; return result; } case 2: return new MinMaxGradient(TintGradient(((MinMaxGradient)(ref original)).gradientMin, color), TintGradient(((MinMaxGradient)(ref original)).gradientMax, color)); case 1: return new MinMaxGradient(Recolor(((MinMaxGradient)(ref original)).colorMin, color), Recolor(((MinMaxGradient)(ref original)).colorMax, color)); default: return new MinMaxGradient(Recolor(((MinMaxGradient)(ref original)).color, color)); } } private static Color Recolor(Color original, Color tint) { //IL_0000: 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_000c: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(original.r, Mathf.Max(original.g, original.b)); return new Color(tint.r * num, tint.g * num, tint.b * num, original.a); } private static Gradient TintGradient(Gradient original, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00c5: Unknown result type (might be due to invalid IL or missing references) Gradient val = new Gradient(); GradientColorKey[] array = (GradientColorKey[])((original != null) ? ((Array)original.colorKeys) : ((Array)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) })); for (int i = 0; i < array.Length; i++) { array[i] = new GradientColorKey(Recolor(array[i].color, color), array[i].time); } val.SetKeys(array, (GradientAlphaKey[])((original != null) ? ((Array)original.alphaKeys) : ((Array)new GradientAlphaKey[2] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }))); if (original != null) { val.mode = original.mode; } return val; } public void Dispose() { //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_0033: 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) //IL_0048: 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_00cb: Unknown result type (might be due to invalid IL or missing references) foreach (ParticleSnapshot particle in particles) { if (!((Object)(object)particle.System == (Object)null)) { MainModule main = particle.System.main; ((MainModule)(ref main)).startColor = particle.Start; ColorOverLifetimeModule colorOverLifetime = particle.System.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = particle.Lifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = particle.LifetimeEnabled; if ((Object)(object)particle.Renderer != (Object)null) { ((Renderer)particle.Renderer).SetPropertyBlock(particle.Properties); } } } foreach (LightSnapshot light in lights) { if ((Object)(object)light.Light != (Object)null) { light.Light.color = light.Color; } } if ((Object)(object)sparks != (Object)null) { sparks.Stop(true, (ParticleSystemStopBehavior)0); } if ((Object)(object)sound != (Object)null) { sound.Stop(); } if ((Object)(object)effects != (Object)null) { effects.SetActive(false); Object.Destroy((Object)(object)effects); } particles.Clear(); lights.Clear(); } internal static void DisposeShared() { if ((Object)(object)pop != (Object)null) { Object.Destroy((Object)(object)pop); } if ((Object)(object)crackle != (Object)null) { Object.Destroy((Object)(object)crackle); } pop = null; crackle = null; } } internal static class ItemIcons { internal const int Size = 256; internal static bool TryLoad(Salt salt, out Texture2D texture, out Sprite sprite) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_011b: Expected O, but got Unknown //IL_0148: 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) texture = null; sprite = null; string name = "FireSalts.ItemIcons." + salt.Prefab + ".png"; using Stream stream = typeof(ItemIcons).Assembly.GetManifestResourceStream(name); if (stream == null) { return false; } try { if (stream.Length < 24 || stream.Length > 524288) { throw new InvalidDataException("Unexpected PNG size"); } byte[] array; using (MemoryStream memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } byte[] array2 = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }; for (int i = 0; i < array2.Length; i++) { if (array[i] != array2[i]) { throw new InvalidDataException("Not a PNG"); } } if (ReadInt(array, 16) != 256 || ReadInt(array, 20) != 256) { throw new InvalidDataException("Item PNG must be 256x256"); } texture = new Texture2D(2, 2, (TextureFormat)4, false, false) { name = salt.Prefab + "_InventoryIcon", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (!ImageConversion.LoadImage(texture, array, true)) { throw new InvalidDataException("PNG decode failed"); } sprite = Sprite.Create(texture, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 256f, 0u, (SpriteMeshType)0); ((Object)sprite).name = salt.Prefab + "_InventorySprite"; return true; } catch (Exception ex) { if ((Object)(object)sprite != (Object)null) { Object.Destroy((Object)(object)sprite); } if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } sprite = null; texture = null; Plugin.Warn("Could not load item artwork for " + salt.Prefab + "; using placeholder: " + ex.Message); return false; } } private static int ReadInt(byte[] data, int at) { return (data[at] << 24) | (data[at + 1] << 16) | (data[at + 2] << 8) | data[at + 3]; } } [BepInPlugin("smeagsmods.firesalts", "Fire Salts", "0.1.1")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class DatabaseAwake { [HarmonyPostfix] private static void Postfix(ObjectDB __instance) { Registration.RegisterItems(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class DatabaseCopy { [HarmonyPostfix] private static void Postfix(ObjectDB __instance) { Registration.RegisterItems(__instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class SceneAwake { [HarmonyPostfix] private static void Postfix(ZNetScene __instance) { Registration.RegisterNetwork(__instance); } } [HarmonyPatch(typeof(Fireplace), "Awake")] private static class FireAwake { [HarmonyPostfix] private static void Postfix(Fireplace __instance) { if (Running) { FireRuntime.Attach(__instance); } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class SaltAwake { [HarmonyPostfix] private static void Postfix(ItemDrop __instance) { if (Salts.Get(__instance) != null) { __instance.m_autoPickup = false; } } } [HarmonyPatch(typeof(ItemDrop), "AutoStackItems")] private static class SaltGroundStack { [HarmonyPrefix] private static bool Prefix(ItemDrop __instance) { return Salts.Get(__instance) == null; } } [HarmonyPatch(typeof(ItemDrop), "OnPlayerDrop")] private static class ArmToss { [HarmonyPostfix] private static void Postfix(ItemDrop __instance) { if (Running && Salts.Get(__instance) != null) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner()) { component.GetZDO().Set("smeagsmods.firesalts.armed.v1", Rules.Expiry(Now, 12)); } } } } [HarmonyPatch(typeof(Humanoid), "UseItem")] private static class TossFromHotbar { [HarmonyPrefix] private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, bool fromInventoryGui) { if (!Running || Salts.Get(item) == null) { return true; } if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return false; } if (fromInventoryGui) { ((Character)__instance).Message((MessageType)2, "Put this salt on your hotbar to toss one, or drop it onto a burning fire.", 0, (Sprite)null, false); return false; } Inventory inventory2 = __instance.GetInventory(); if ((inventory != null && inventory != inventory2) || !inventory2.ContainsItem(item) || Time.unscaledTime < nextToss) { return false; } if (((Character)__instance).IsDead() || ((Character)__instance).InAttack() || ((Character)__instance).IsTeleporting()) { return false; } nextToss = Time.unscaledTime + 0.6f; __instance.DropItem(inventory2, item, 1); return false; } } public const string Id = "smeagsmods.firesalts"; internal static Plugin Instance; internal ConfigEntry<bool> Visuals; internal ConfigEntry<bool> Sound; private Harmony harmony; private float nextScan; private static float nextToss; internal static bool Running { get { if ((Object)(object)Instance != (Object)null) { return ((Behaviour)Instance).isActiveAndEnabled; } return false; } } internal static bool HasGraphics => (int)SystemInfo.graphicsDeviceType != 4; internal static long Now { get { if (!((Object)(object)ZNet.instance == (Object)null)) { return ZNet.instance.GetTime().Ticks; } return 0L; } } private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Instance = this; Visuals = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "Visuals", true, "Show temporary salt colors and bounded sparks. Does not change server consumption or duration."); Sound = ((BaseUnityPlugin)this).Config.Bind<bool>("Client", "Sound", true, "Play quiet decorative crackles and pops within 12 metres."); harmony = new Harmony("smeagsmods.firesalts"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Fire Salts 0.1.1 loaded; approved inventory art. All peers require the same version."); } private void Update() { if (!(Time.unscaledTime < nextScan)) { nextScan = Time.unscaledTime + 0.1f; FireRuntime.TickAuthority(); if (HasGraphics) { FireRuntime.SelectVisuals(); } } } private void LateUpdate() { if (HasGraphics) { FireRuntime.TickVisuals(); } } private void OnDisable() { FireRuntime.RestoreAll(); } private void OnDestroy() { FireRuntime.DetachAll(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } Registration.Dispose(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } internal static void Log(string message) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)message); } } internal static void Warn(string message) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)message); } } } internal static class Reaction { internal static bool Apply(int salt, long now, long armedUntil, Action<long> setArmed, Func<bool> removeOne, Action<string> publish) { if (!Rules.IsSalt(salt) || !Rules.IsArmed(armedUntil, now)) { return false; } setArmed(0L); if (!removeOne()) { setArmed(armedUntil); return false; } publish(Rules.Pack(salt, now)); return true; } } internal static class Registration { private static GameObject root; private static readonly Dictionary<string, GameObject> prefabs = new Dictionary<string, GameObject>(); private static readonly List<Object> owned = new List<Object>(); private static readonly List<Recipe> recipes = new List<Recipe>(); private static readonly List<ObjectDB> databases = new List<ObjectDB>(); private static readonly MethodInfo updateRegisters = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); private static readonly FieldInfo namedPrefabs = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); internal static void RegisterItems(ObjectDB db) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_00ed: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_015a: 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_020d: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Running || (Object)(object)db == (Object)null || (Object)(object)db.GetItemPrefab("Resin") == (Object)null) { return; } if (!databases.Contains(db)) { databases.Add(db); } if ((Object)(object)root == (Object)null) { root = new GameObject("FireSalts_Prefabs"); root.SetActive(false); Object.DontDestroyOnLoad((Object)(object)root); } Salt[] all = Salts.All; foreach (Salt salt in all) { if (!prefabs.TryGetValue(salt.Prefab, out var value)) { if ((Object)(object)db.GetItemPrefab(salt.Prefab) != (Object)null) { throw new InvalidOperationException("Fire Salts prefab name is already registered: " + salt.Prefab); } value = Object.Instantiate<GameObject>(db.GetItemPrefab("Resin"), root.transform, false); ((Object)value).name = salt.Prefab; value.transform.localPosition = Vector3.zero; value.transform.localRotation = Quaternion.identity; ItemDrop component = value.GetComponent<ItemDrop>(); ItemData val = new ItemData(); val.m_dropPrefab = value; SharedData val2 = new SharedData(); val2.m_name = salt.Name; val2.m_description = "A pinch of " + salt.Name.ToLowerInvariant() + ". Toss onto a burning campfire, hearth or bonfire for 30 seconds of colored flame.\nHotbar: toss one. Misses can be picked up by hand.\n<color=#b6a8c8>Dropped world item uses a tinted native resin model.</color>"; val2.m_itemType = (ItemType)1; val2.m_icons = (Sprite[])(object)new Sprite[1] { MakeIcon(salt) }; val2.m_maxStackSize = 20; val2.m_weight = 0.1f; val2.m_maxQuality = 1; val2.m_autoStack = false; val2.m_teleportable = true; val.m_shared = val2; component.m_itemData = val; component.m_autoPickup = false; MeshRenderer[] componentsInChildren = value.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val3 in componentsInChildren) { Material[] sharedMaterials = ((Renderer)val3).sharedMaterials; for (int k = 0; k < sharedMaterials.Length; k++) { if (!((Object)(object)sharedMaterials[k] == (Object)null)) { Material val4 = new Material(sharedMaterials[k]) { name = salt.Prefab + "_Placeholder" }; if (val4.HasProperty("_Color")) { val4.SetColor("_Color", salt.Color); } sharedMaterials[k] = val4; owned.Add((Object)(object)val4); } } ((Renderer)val3).sharedMaterials = sharedMaterials; } prefabs.Add(salt.Prefab, value); } if (!db.m_items.Contains(value)) { db.m_items.Add(value); } } updateRegisters.Invoke(db, null); AddRecipes(db); if ((Object)(object)ZNetScene.instance != (Object)null) { AddNetworkPrefabs(ZNetScene.instance); } } private static Sprite MakeIcon(Salt salt) { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_01ab: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_0161: 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_0166: Unknown result type (might be due to invalid IL or missing references) if (ItemIcons.TryLoad(salt, out var texture, out var sprite)) { owned.Add((Object)(object)texture); owned.Add((Object)(object)sprite); return sprite; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = salt.Prefab + "_PlaceholderIcon", filterMode = (FilterMode)0 }; Color[] array = (Color[])(object)new Color[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num = Math.Abs((float)j - 32f) / 21f + Math.Abs((float)i - 35f) / 25f; if (num < 1f) { array[i * 64 + j] = Color.Lerp(salt.Color * 0.55f, Color.white, (j < 32) ? 0.3f : 0.04f); } if (num < 0.85f && j < 31) { array[i * 64 + j] = salt.Color; } for (int k = 0; k < salt.Id; k++) { if (Math.Abs(j - (26 + k * 7)) <= 2 && i >= 4 && i <= 8) { array[i * 64 + j] = Color.white; } } if (j >= 52 && i >= 52) { array[i * 64 + j] = (((j / 3 + i / 3) % 2 == 0) ? Color.magenta : Color.black); } } } val.SetPixels(array); val.Apply(); Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); owned.Add((Object)(object)val); owned.Add((Object)(object)val2); return val2; } private static void AddRecipes(ObjectDB db) { CraftingStation val = (from r in db.m_recipes where (Object)(object)r != (Object)null && (Object)(object)r.m_craftingStation != (Object)null select r.m_craftingStation).FirstOrDefault((Func<CraftingStation, bool>)((CraftingStation s) => ((Object)s).name == "piece_workbench")); if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab("piece_workbench"); val = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null); } if ((Object)(object)val == (Object)null) { return; } Salt[] all = Salts.All; foreach (Salt salt in all) { string name = "Recipe_" + salt.Prefab; if (db.m_recipes.Any((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name == name)) { continue; } GameObject itemPrefab = db.GetItemPrefab(salt.Ingredient); GameObject itemPrefab2 = db.GetItemPrefab("Resin"); GameObject itemPrefab3 = db.GetItemPrefab("Coal"); if ((Object)(object)itemPrefab == (Object)null || (Object)(object)itemPrefab2 == (Object)null || (Object)(object)itemPrefab3 == (Object)null) { Plugin.Warn("Recipe deferred: missing native ingredient for " + name); continue; } Recipe val2 = ((IEnumerable<Recipe>)recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => ((Object)r).name == name)); if ((Object)(object)val2 == (Object)null) { val2 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val2).name = name; val2.m_item = prefabs[salt.Prefab].GetComponent<ItemDrop>(); val2.m_amount = 3; val2.m_craftingStation = val; val2.m_minStationLevel = 1; val2.m_enabled = true; val2.m_resources = (Requirement[])(object)new Requirement[3] { Requirement(itemPrefab2, 2), Requirement(itemPrefab3, 1), Requirement(itemPrefab, 1) }; recipes.Add(val2); } db.m_recipes.Add(val2); } } private static Requirement Requirement(GameObject item, int amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown return new Requirement { m_resItem = item.GetComponent<ItemDrop>(), m_amount = amount, m_amountPerLevel = 0, m_recover = false }; } internal static void RegisterNetwork(ZNetScene scene) { RegisterItems(ObjectDB.instance); AddNetworkPrefabs(scene); if ((Object)(object)ObjectDB.instance != (Object)null) { AddRecipes(ObjectDB.instance); } } private static void AddNetworkPrefabs(ZNetScene scene) { Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)namedPrefabs.GetValue(scene); foreach (KeyValuePair<string, GameObject> prefab in prefabs) { int stableHashCode = StringExtensionMethods.GetStableHashCode(prefab.Key); if (dictionary.TryGetValue(stableHashCode, out var value) && (Object)(object)value != (Object)(object)prefab.Value) { throw new InvalidOperationException("Fire Salts network prefab hash collision: " + prefab.Key); } dictionary[stableHashCode] = prefab.Value; if (!scene.m_prefabs.Contains(prefab.Value)) { scene.m_prefabs.Add(prefab.Value); } } } internal static void Dispose() { foreach (ObjectDB database in databases) { if (!((Object)(object)database == (Object)null)) { database.m_items.RemoveAll((GameObject p) => prefabs.Values.Contains(p)); database.m_recipes.RemoveAll((Recipe r) => recipes.Contains(r)); updateRegisters.Invoke(database, null); } } if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene instance = ZNetScene.instance; Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)namedPrefabs.GetValue(instance); foreach (KeyValuePair<string, GameObject> prefab in prefabs) { int stableHashCode = StringExtensionMethods.GetStableHashCode(prefab.Key); if (dictionary.TryGetValue(stableHashCode, out var value) && (Object)(object)value == (Object)(object)prefab.Value) { dictionary.Remove(stableHashCode); } instance.m_prefabs.Remove(prefab.Value); } } foreach (Recipe recipe in recipes) { Object.Destroy((Object)(object)recipe); } if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } foreach (Object item in owned) { if (item != (Object)null) { Object.Destroy(item); } } recipes.Clear(); prefabs.Clear(); owned.Clear(); databases.Clear(); root = null; } } internal static class Rules { internal const int SaltCount = 3; internal const int DurationSeconds = 30; internal const int ArmedSeconds = 12; internal const int MaxVisualFires = 8; internal const int MaxScansPerTick = 16; internal const int MaxExtraParticles = 24; internal const float VisualRange = 32f; internal const string StateKey = "smeagsmods.firesalts.state.v1"; internal const string ArmedKey = "smeagsmods.firesalts.armed.v1"; internal static bool IsSalt(int id) { if (id >= 1) { return id <= 3; } return false; } internal static long Expiry(long start, int seconds) { if (start <= 0 || start > DateTime.MaxValue.Ticks - (long)seconds * 10000000L) { return 0L; } return start + (long)seconds * 10000000L; } internal static bool IsArmed(long until, long now) { if (now > 0 && until > now) { return until - now <= 120000000; } return false; } internal static string Pack(int salt, long start) { if (!IsSalt(salt) || Expiry(start, 30) == 0L) { return ""; } return salt.ToString(CultureInfo.InvariantCulture) + ":" + start.ToString(CultureInfo.InvariantCulture); } internal static bool TryState(string raw, long now, out int salt, out long start) { salt = 0; start = 0L; if (now <= 0 || string.IsNullOrEmpty(raw) || raw.Length > 24) { return false; } string[] array = raw.Split(':'); if (array.Length != 2 || !int.TryParse(array[0], NumberStyles.None, CultureInfo.InvariantCulture, out salt) || !long.TryParse(array[1], NumberStyles.None, CultureInfo.InvariantCulture, out start) || !IsSalt(salt)) { return false; } long num = Expiry(start, 30); if (start <= now) { return num > now; } return false; } internal static bool CanConsume(bool fireOwner, bool itemOwner, bool burning, bool active, bool inVolume, int stack, int salt, long armedUntil, long now) { if (fireOwner && itemOwner && burning && !active && inVolume && stack > 0 && IsSalt(salt)) { return IsArmed(armedUntil, now); } return false; } internal static bool InVolume(string prefab, float x, float y, float z) { if (float.IsNaN(x) || float.IsNaN(y) || float.IsNaN(z)) { return false; } switch (prefab) { case "fire_pit": if (x * x + z * z <= 0.5184f && y >= 0.04f) { return y <= 1.15f; } return false; case "hearth": if (Math.Abs(x) <= 0.8f && Math.Abs(z) <= 1.35f && y >= 0.04f) { return y <= 1.3f; } return false; case "bonfire": if (x * x + z * z <= 1.3225f && y >= 0.2f) { return y <= 2.8f; } return false; default: return false; } } internal static int Pulse(long now, long start) { return (int)Math.Max(0L, (now - start) / 20000000); } } internal sealed class Salt { internal readonly int Id; internal readonly string Prefab; internal readonly string Name; internal readonly string Ingredient; internal readonly Color Color; internal Salt(int id, string prefab, string name, string ingredient, Color color) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Id = id; Prefab = prefab; Name = name; Ingredient = ingredient; Color = color; } } internal static class Salts { internal static readonly Salt[] All = new Salt[3] { new Salt(1, "FireSalts_Seaglass", "Seaglass Salts", "GreydwarfEye", new Color(0.12f, 1f, 0.68f)), new Salt(2, "FireSalts_Roseember", "Roseember Salts", "Raspberry", new Color(1f, 0.2f, 0.42f)), new Salt(3, "FireSalts_Moonviolet", "Moonviolet Salts", "Blueberries", new Color(0.6f, 0.26f, 1f)) }; internal static Salt Get(int id) { if (!Rules.IsSalt(id)) { return null; } return All[id - 1]; } internal static Salt Get(ItemData item) { if ((Object)(object)item?.m_dropPrefab == (Object)null) { return null; } string name = ((Object)item.m_dropPrefab).name; Salt[] all = All; foreach (Salt salt in all) { if (name == salt.Prefab) { return salt; } } return null; } internal static Salt Get(ItemDrop item) { if ((Object)(object)item == (Object)null) { return null; } string text = ((Object)((Component)item).gameObject).name.Replace("(Clone)", ""); Salt[] all = All; foreach (Salt salt in all) { if (text == salt.Prefab) { return salt; } } return null; } } }