Decompiled source of DimmerCombatParticleEffects v1.0.0

plugins\DimmerCombatParticleEffects.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DimmerCombatParticleEffects.HitVfx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DimmerCombatParticleEffects")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+877abc854ffcba11777d442d07b0edd8ef31a699")]
[assembly: AssemblyProduct("DimmerCombatParticleEffects")]
[assembly: AssemblyTitle("DimmerCombatParticleEffects")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DimmerCombatParticleEffects
{
	[BepInPlugin("wheeze.valheim.dimmercombatparticleeffects", "Dimmer Combat Particle Effects", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "wheeze.valheim.dimmercombatparticleeffects";

		public const string PluginName = "Dimmer Combat Particle Effects";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			HitVfxSettings.Bind(((BaseUnityPlugin)this).Config);
			ParticleProbe.Reset();
			_harmony = new Harmony("wheeze.valheim.dimmercombatparticleeffects");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)string.Format("{0} {1} loaded; {2} method(s) patched.", "Dimmer Combat Particle Effects", "1.0.0", _harmony.GetPatchedMethods().Count()));
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			HitEffectScope.Reset();
			Instance = null;
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"Dimmer Combat Particle Effects unloaded.");
			}
		}
	}
}
namespace DimmerCombatParticleEffects.Patches
{
	[HarmonyPatch(typeof(Aoe), "OnHit", new Type[]
	{
		typeof(Collider),
		typeof(Vector3)
	})]
	internal static class AoeOnHitPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Aoe __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampen(HitVfxSettings.AoeHits))
			{
				HitEffectScope.Arm(__instance.m_hitEffects);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	internal static class AttackHitEffects
	{
		public static void Arm(Attack attack)
		{
			if (attack != null && HitVfxSettings.ShouldDampen(HitVfxSettings.WeaponHits))
			{
				HitEffectScope.Arm(attack.m_hitEffect);
				ItemData weapon = attack.m_weapon;
				if (weapon?.m_shared != null)
				{
					HitEffectScope.Arm(weapon.m_shared.m_hitEffect);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "DoMeleeAttack", new Type[] { })]
	internal static class AttackDoMeleeAttackPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Attack __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			AttackHitEffects.Arm(__instance);
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(Attack), "DoAreaAttack", new Type[] { })]
	internal static class AttackDoAreaAttackPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Attack __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			AttackHitEffects.Arm(__instance);
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage", new Type[]
	{
		typeof(HitData),
		typeof(bool),
		typeof(bool),
		typeof(DamageModifier)
	})]
	internal static class CharacterApplyDamagePatch
	{
		[HarmonyPrefix]
		private static void Prefix(Character __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampenCharacter(__instance))
			{
				HitEffectScope.Arm(__instance.m_hitEffects);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage", new Type[]
	{
		typeof(long),
		typeof(HitData)
	})]
	internal static class CharacterRpcDamagePatch
	{
		[HarmonyPrefix]
		private static void Prefix(Character __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampenCharacter(__instance))
			{
				HitEffectScope.Arm(__instance.m_critHitEffects);
				HitEffectScope.Arm(__instance.m_backstabHitEffects);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(EffectList), "Create")]
	internal static class EffectListCreatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(EffectList __instance, GameObject[] __result)
		{
			if (__result == null || __result.Length == 0)
			{
				return;
			}
			bool flag = HitEffectScope.Depth > 0 && HitEffectScope.IsArmed(__instance);
			if (flag)
			{
				ParticleDampener.Apply(__result, HitVfxSettings.Opacity.Value, HitVfxSettings.Brightness.Value, HitVfxSettings.Size.Value);
			}
			if (HitVfxSettings.LogAllEffects.Value || (flag && HitVfxSettings.LogDampenedEffects.Value))
			{
				string text = (flag ? "dampened" : "skipped");
				for (int i = 0; i < __result.Length; i++)
				{
					Plugin.Log.LogInfo((object)("[HitVfx " + text + "] " + ParticleDampener.Describe(__result[i])));
				}
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit", new Type[]
	{
		typeof(Collider),
		typeof(Vector3),
		typeof(bool),
		typeof(Vector3)
	})]
	internal static class ProjectileOnHitPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Projectile __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampen(HitVfxSettings.ProjectileHits))
			{
				HitEffectScope.Arm(__instance.m_hitEffects);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(SE_Burning), "UpdateStatusEffect", new Type[] { typeof(float) })]
	internal static class SeBurningUpdatePatch
	{
		[HarmonyPrefix]
		private static void Prefix(SE_Burning __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampenStatusEffect(((StatusEffect)__instance).m_character))
			{
				HitEffectScope.Arm(__instance.m_tickEffect);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(SE_Poison), "UpdateStatusEffect", new Type[] { typeof(float) })]
	internal static class SePoisonUpdatePatch
	{
		[HarmonyPrefix]
		private static void Prefix(SE_Poison __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampenStatusEffect(((StatusEffect)__instance).m_character))
			{
				HitEffectScope.Arm(__instance.m_tickEffect);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(SE_Stats), "UpdateStatusEffect", new Type[] { typeof(float) })]
	internal static class SeStatsUpdatePatch
	{
		[HarmonyPrefix]
		private static void Prefix(SE_Stats __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampenStatusEffect(((StatusEffect)__instance).m_character))
			{
				HitEffectScope.Arm(__instance.m_tickEffect);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
	[HarmonyPatch(typeof(StatusEffect), "TriggerStartEffects", new Type[] { })]
	internal static class StatusEffectTriggerStartEffectsPatch
	{
		[HarmonyPrefix]
		private static void Prefix(StatusEffect __instance, out int __state)
		{
			__state = HitEffectScope.Depth;
			if (HitVfxSettings.ShouldDampenStatusEffect(__instance.m_character))
			{
				HitEffectScope.Arm(__instance.m_startEffects);
			}
		}

		[HarmonyFinalizer]
		private static void Finalizer(int __state)
		{
			HitEffectScope.UnwindTo(__state);
		}
	}
}
namespace DimmerCombatParticleEffects.HitVfx
{
	internal static class HitEffectScope
	{
		private static readonly List<EffectList> Armed = new List<EffectList>(8);

		public static int Depth => Armed.Count;

		public static void Arm(EffectList list)
		{
			if (list != null)
			{
				Armed.Add(list);
			}
		}

		public static void UnwindTo(int depth)
		{
			if (depth < 0)
			{
				depth = 0;
			}
			if (Armed.Count > depth)
			{
				Armed.RemoveRange(depth, Armed.Count - depth);
			}
		}

		public static bool IsArmed(EffectList list)
		{
			for (int num = Armed.Count - 1; num >= 0; num--)
			{
				if (Armed[num] == list)
				{
					return true;
				}
			}
			return false;
		}

		public static void Reset()
		{
			Armed.Clear();
		}
	}
	internal static class HitVfxSettings
	{
		private const string SectionGeneral = "1 - General";

		private const string SectionStrength = "2 - Strength";

		private const string SectionSources = "3 - Sources";

		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<float> Opacity;

		public static ConfigEntry<float> Brightness;

		public static ConfigEntry<float> Size;

		public static ConfigEntry<bool> CharacterHits;

		public static ConfigEntry<bool> WeaponHits;

		public static ConfigEntry<bool> ProjectileHits;

		public static ConfigEntry<bool> AoeHits;

		public static ConfigEntry<bool> StatusEffectVisuals;

		public static ConfigEntry<bool> IncludePlayerHits;

		public static ConfigEntry<bool> LogDampenedEffects;

		public static ConfigEntry<bool> LogAllEffects;

		public static void Bind(ConfigFile cfg)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			Enabled = cfg.Bind<bool>("1 - General", "Enabled", true, "Dampen the particle effects that burst out of a target when it is struck. Lights are never touched, so hits still illuminate dark areas.");
			LogDampenedEffects = cfg.Bind<bool>("1 - General", "Log dampened effects", false, "Write one line to the BepInEx log for every effect that gets dampened, listing its particle systems, its lights, and any mesh renderers this mod does not touch. Diagnostic only - leave off for normal play.");
			LogAllEffects = cfg.Bind<bool>("1 - General", "Log every effect", false, "Log every effect the game spawns, including the ones this mod leaves alone, marked dampened or skipped. Use this to find an effect that is still too loud: whatever is bothering you will appear in the log as skipped, which names the prefab and tells us which spawn path is still uncovered. Very noisy - diagnostic only.");
			Opacity = cfg.Bind<float>("2 - Strength", "Opacity", 0.35f, new ConfigDescription("Alpha multiplier applied to hit particles. 1 is vanilla, 0 is invisible. Lower this until enemy wind-up animations read clearly through the effect.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			Brightness = cfg.Bind<float>("2 - Strength", "Brightness", 1f, new ConfigDescription("Colour multiplier applied to hit particles. Leave at 1 unless an effect stays bright after lowering Opacity, which means its shader blends additively and ignores alpha. Lowering this dims those without touching any light source.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			Size = cfg.Bind<float>("2 - Strength", "Size", 1f, new ConfigDescription("Size multiplier applied to hit particles. 1 is vanilla. Lower it to shrink the area an effect covers instead of only fading it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			CharacterHits = cfg.Bind<bool>("3 - Sources", "Character hit effects", true, "Dampen the burst the struck creature itself spawns: blood, impact sparks, and the extra crit and backstab bursts.");
			WeaponHits = cfg.Bind<bool>("3 - Sources", "Weapon hit effects", true, "Dampen the burst the attacking weapon spawns at the point of impact. This is where the elemental effects live - fire, frost, lightning, poison, spirit - and it is usually the worst offender for hiding an enemy.");
			ProjectileHits = cfg.Bind<bool>("3 - Sources", "Projectile hit effects", true, "Dampen the burst an arrow, bolt, or staff projectile spawns where it lands. Water splashes are a separate effect and are left alone.");
			AoeHits = cfg.Bind<bool>("3 - Sources", "Area of effect hit effects", true, "Dampen the burst an area attack spawns on each thing it hits: atgeir sweeps, bombs, ground slams.");
			StatusEffectVisuals = cfg.Bind<bool>("3 - Sources", "Status effect visuals on creatures", true, "Dampen the lingering aura a status effect puts on a creature - the flames on a burning enemy, the frost shell, the poison cloud - and the burst it re-spawns on every damage tick. These persist for the whole duration rather than flashing once, so they hide a creature far longer than the impact burst does. Never applied to players.");
			IncludePlayerHits = cfg.Bind<bool>("3 - Sources", "Include hits on players", false, "Also dampen the character hit effects spawned when a player is the one struck. Off by default so your own damage feedback stays at full strength.");
		}

		public static bool ShouldDampenCharacter(Character victim)
		{
			if (!Enabled.Value || !CharacterHits.Value || (Object)(object)victim == (Object)null)
			{
				return false;
			}
			if (!IncludePlayerHits.Value)
			{
				return !victim.IsPlayer();
			}
			return true;
		}

		public static bool ShouldDampenStatusEffect(Character carrier)
		{
			if (Enabled.Value && StatusEffectVisuals.Value && (Object)(object)carrier != (Object)null)
			{
				return !carrier.IsPlayer();
			}
			return false;
		}

		public static bool ShouldDampen(ConfigEntry<bool> source)
		{
			if (Enabled.Value)
			{
				return source.Value;
			}
			return false;
		}
	}
	internal static class ParticleDampener
	{
		public static void Apply(GameObject[] spawned, float alpha, float brightness, float size)
		{
			if (spawned != null)
			{
				for (int i = 0; i < spawned.Length; i++)
				{
					Apply(spawned[i], alpha, brightness, size);
				}
			}
		}

		public static void Apply(GameObject root, float alpha, float brightness, float size)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_0083: 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_0097: 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_010c: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			bool flag = alpha < 1f || brightness < 1f;
			bool flag2 = size < 1f;
			if (!flag && !flag2)
			{
				return;
			}
			bool active = ParticleProbe.Active;
			ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MainModule main = val.main;
				MinMaxGradient beforeColour = (MinMaxGradient)(active ? ((MainModule)(ref main)).startColor : default(MinMaxGradient));
				MinMaxCurve beforeSize = (MinMaxCurve)(active ? ((MainModule)(ref main)).startSize : default(MinMaxCurve));
				if (flag)
				{
					((MainModule)(ref main)).startColor = ScaleGradient(((MainModule)(ref main)).startColor, alpha, brightness);
				}
				if (flag2)
				{
					if (((MainModule)(ref main)).startSize3D)
					{
						((MainModule)(ref main)).startSizeX = ScaleCurve(((MainModule)(ref main)).startSizeX, size);
						((MainModule)(ref main)).startSizeY = ScaleCurve(((MainModule)(ref main)).startSizeY, size);
						((MainModule)(ref main)).startSizeZ = ScaleCurve(((MainModule)(ref main)).startSizeZ, size);
					}
					else
					{
						((MainModule)(ref main)).startSize = ScaleCurve(((MainModule)(ref main)).startSize, size);
					}
				}
				if (active)
				{
					ParticleProbe.Report(root, val, beforeColour, beforeSize);
				}
			}
		}

		public static string Describe(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return "<destroyed>";
			}
			int num = root.GetComponentsInChildren<ParticleSystem>(true).Length;
			int num2 = root.GetComponentsInChildren<Light>(true).Length;
			int num3 = 0;
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (!(componentsInChildren[i] is ParticleSystemRenderer))
				{
					num3++;
				}
			}
			return $"{((Object)root).name}: {num} particle system(s), " + $"{num2} light(s), {num3} non-particle renderer(s)";
		}

		private static MinMaxGradient ScaleGradient(MinMaxGradient source, float alpha, float brightness)
		{
			//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_0022: Expected I4, but got Unknown
			//IL_0026: 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_0032: 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_007d: 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_0041: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystemGradientMode mode = ((MinMaxGradient)(ref source)).mode;
			switch ((int)mode)
			{
			case 0:
				return new MinMaxGradient(Scale(((MinMaxGradient)(ref source)).color, alpha, brightness));
			case 2:
				return new MinMaxGradient(Scale(((MinMaxGradient)(ref source)).colorMin, alpha, brightness), Scale(((MinMaxGradient)(ref source)).colorMax, alpha, brightness));
			case 1:
			case 4:
			{
				MinMaxGradient result = default(MinMaxGradient);
				((MinMaxGradient)(ref result))..ctor(Scale(((MinMaxGradient)(ref source)).gradient, alpha, brightness));
				((MinMaxGradient)(ref result)).mode = ((MinMaxGradient)(ref source)).mode;
				return result;
			}
			case 3:
				return new MinMaxGradient(Scale(((MinMaxGradient)(ref source)).gradientMin, alpha, brightness), Scale(((MinMaxGradient)(ref source)).gradientMax, alpha, brightness));
			default:
				return source;
			}
		}

		private static Color Scale(Color colour, float alpha, float brightness)
		{
			//IL_0000: 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_0010: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			return new Color(colour.r * brightness, colour.g * brightness, colour.b * brightness, colour.a * alpha);
		}

		private static Gradient Scale(Gradient source, float alpha, float brightness)
		{
			//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_009d: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0056: 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)
			if (source == null)
			{
				return null;
			}
			GradientColorKey[] colorKeys = source.colorKeys;
			GradientAlphaKey[] alphaKeys = source.alphaKeys;
			if (brightness < 1f)
			{
				for (int i = 0; i < colorKeys.Length; i++)
				{
					Color color = colorKeys[i].color;
					colorKeys[i].color = new Color(color.r * brightness, color.g * brightness, color.b * brightness, color.a);
				}
			}
			if (alpha < 1f)
			{
				for (int j = 0; j < alphaKeys.Length; j++)
				{
					alphaKeys[j].alpha *= alpha;
				}
			}
			Gradient val = new Gradient
			{
				mode = source.mode,
				colorSpace = source.colorSpace
			};
			val.SetKeys(colorKeys, alphaKeys);
			return val;
		}

		private static MinMaxCurve ScaleCurve(MinMaxCurve curve, float multiplier)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			((MinMaxCurve)(ref curve)).constantMin = ((MinMaxCurve)(ref curve)).constantMin * multiplier;
			((MinMaxCurve)(ref curve)).constantMax = ((MinMaxCurve)(ref curve)).constantMax * multiplier;
			((MinMaxCurve)(ref curve)).curveMultiplier = ((MinMaxCurve)(ref curve)).curveMultiplier * multiplier;
			return curve;
		}
	}
	internal static class ParticleProbe
	{
		private const int MaxLines = 60;

		private static int _used;

		public static bool Active
		{
			get
			{
				if (HitVfxSettings.LogDampenedEffects.Value)
				{
					return _used < 60;
				}
				return false;
			}
		}

		public static void Reset()
		{
			_used = 0;
		}

		public static void Report(GameObject root, ParticleSystem ps, MinMaxGradient beforeColour, MinMaxCurve beforeSize)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (_used < 60)
			{
				_used++;
				MainModule main = ps.main;
				ManualLogSource log = Plugin.Log;
				string[] obj = new string[10]
				{
					"[Probe] ",
					((Object)root).name,
					"/",
					((Object)ps).name,
					" ",
					$"colour(mode={((MinMaxGradient)(ref beforeColour)).mode} alpha {Alpha(beforeColour):0.00} -> {Alpha(((MainModule)(ref main)).startColor):0.00}) ",
					null,
					null,
					null,
					null
				};
				object[] obj2 = new object[4]
				{
					((MinMaxCurve)(ref beforeSize)).mode,
					((MinMaxCurve)(ref beforeSize)).constantMax,
					null,
					null
				};
				MinMaxCurve startSize = ((MainModule)(ref main)).startSize;
				obj2[2] = ((MinMaxCurve)(ref startSize)).constantMax;
				obj2[3] = ((MainModule)(ref main)).startSize3D;
				obj[6] = string.Format("size(mode={0} {1:0.000} -> {2:0.000} 3d={3}) ", obj2);
				obj[7] = $"playing={ps.isPlaying} emitted={ps.particleCount} ";
				obj[8] = "renderer=";
				obj[9] = RendererState(ps);
				log.LogInfo((object)string.Concat(obj));
				if ((Object)(object)Plugin.Instance != (Object)null)
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(Recheck(ps));
				}
			}
		}

		private static IEnumerator Recheck(ParticleSystem ps)
		{
			yield return (object)new WaitForSeconds(0.3f);
			if (!((Object)(object)ps == (Object)null))
			{
				MainModule main = ps.main;
				ManualLogSource log = Plugin.Log;
				string text = $"[Probe +0.3s] {((Object)ps).name} alpha={Alpha(((MainModule)(ref main)).startColor):0.00} ";
				MinMaxCurve startSize = ((MainModule)(ref main)).startSize;
				log.LogInfo((object)(text + $"size={((MinMaxCurve)(ref startSize)).constantMax:0.000} emitted={ps.particleCount}"));
			}
		}

		private static float Alpha(MinMaxGradient gradient)
		{
			//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_0022: Expected I4, but got Unknown
			//IL_0026: 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)
			ParticleSystemGradientMode mode = ((MinMaxGradient)(ref gradient)).mode;
			switch ((int)mode)
			{
			case 0:
				return ((MinMaxGradient)(ref gradient)).color.a;
			case 2:
				return ((MinMaxGradient)(ref gradient)).colorMax.a;
			case 1:
			case 4:
				return TopAlpha(((MinMaxGradient)(ref gradient)).gradient);
			case 3:
				return TopAlpha(((MinMaxGradient)(ref gradient)).gradientMax);
			default:
				return -1f;
			}
		}

		private static float TopAlpha(Gradient gradient)
		{
			if (gradient == null)
			{
				return -1f;
			}
			float num = 0f;
			GradientAlphaKey[] alphaKeys = gradient.alphaKeys;
			for (int i = 0; i < alphaKeys.Length; i++)
			{
				if (alphaKeys[i].alpha > num)
				{
					num = alphaKeys[i].alpha;
				}
			}
			return num;
		}

		private static string RendererState(ParticleSystem ps)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystemRenderer component = ((Component)ps).GetComponent<ParticleSystemRenderer>();
			if ((Object)(object)component == (Object)null)
			{
				return "<none>";
			}
			string arg = (((Object)(object)((Renderer)component).sharedMaterial != (Object)null && (Object)(object)((Renderer)component).sharedMaterial.shader != (Object)null) ? ((Object)((Renderer)component).sharedMaterial.shader).name : "<no material>");
			return string.Format("{0}/{1}/{2}", ((Renderer)component).enabled ? "on" : "off", component.renderMode, arg);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}