Decompiled source of Runic Barrier v1.0.2
plugins/RunicBarrier.dll
Decompiled 3 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SideLoader; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("RunicBarrier")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RunicBarrier")] [assembly: AssemblyTitle("RunicBarrier")] [assembly: AssemblyVersion("1.0.2.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 RunicBarrier { [HarmonyPatch(typeof(Item), "Start")] internal static class Item_Start_NameSync { private static readonly FieldRef<Item, string> ItemRawName = AccessTools.FieldRefAccess<Item, string>("m_name"); private static int _logged; private const int LOG_LIMIT = 5; [HarmonyPriority(0)] private static void Postfix(Item __instance) { try { if (!Object.op_Implicit((Object)(object)__instance) || string.IsNullOrEmpty(__instance.UID)) { return; } string text = ItemRawName.Invoke(__instance); if (string.IsNullOrEmpty(text)) { return; } string text2 = ((__instance.UID.Length > 10) ? __instance.UID.Substring(0, 10) : __instance.UID); string text3 = __instance.ItemID + "_" + text.Replace(" ", string.Empty) + "_" + text2; string text4 = __instance.ToShortString(); if (!(((Object)__instance).name != text3) && !(text3 == text4)) { ((Object)__instance).name = text4; if (_logged < 5) { _logged++; RunicBarrierPlugin.Log.LogMessage((object)("[NameSync] (" + _logged + "/" + 5 + ") renamed '" + text3 + "' -> '" + text4 + "' to match the other clients")); } } } catch (Exception ex) { RunicBarrierPlugin.Log.LogError((object)("[NameSync] rename check threw: " + ex)); } } } internal static class VFXMap { private const VFXPrefabs SUBJECT = (VFXPrefabs)52; private static readonly VFXPrefabs[] AlsoSummarise; private const string EMBER_SOURCE_STATUS = "RunicBarrier"; private const string EMBER = "Ember"; private const int MAX_ATTEMPTS = 15; private static bool _done; private static int _attempts; private static bool _gaveUp; internal static void TryOnce() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (_done || _gaveUp) { return; } _attempts++; try { GameObject val = Fetch((VFXPrefabs)52); if ((Object)(object)val == (Object)null) { if (_attempts >= 15) { _gaveUp = true; RunicBarrierPlugin.Log.LogWarning((object)("[RunicBarrier] vfx map gave up: " + ((object)(VFXPrefabs)52/*cast due to .constrained prefix*/).ToString() + " never appeared in SideLoader's cache after " + _attempts + " attempts.")); } } else { ReportEmberColour(); Report(((object)(VFXPrefabs)52/*cast due to .constrained prefix*/).ToString(), val.transform); for (int i = 0; i < AlsoSummarise.Length; i++) { Summarise(AlsoSummarise[i]); } _done = true; } } catch (Exception ex) { RunicBarrierPlugin.Log.LogError((object)("[RunicBarrier] vfx map threw: " + ex)); _gaveUp = true; } } private static GameObject Fetch(VFXPrefabs which) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) try { return SL_PlayVFX.GetVfxSystem(which); } catch (Exception) { return null; } } private static void ReportEmberColour() { //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_009f: Unknown result type (might be due to invalid IL or missing references) StatusEffect statusEffectPrefab = ResourcesPrefabManager.Instance.GetStatusEffectPrefab("RunicBarrier"); if (!Object.op_Implicit((Object)(object)statusEffectPrefab) || !Object.op_Implicit((Object)(object)statusEffectPrefab.FXPrefab)) { RunicBarrierPlugin.Log.LogMessage((object)"[RunicBarrier] vfx map: could not read Ember's colour - status 'RunicBarrier' or its FXPrefab is missing."); return; } Transform[] componentsInChildren = ((Component)statusEffectPrefab.FXPrefab).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (Object.op_Implicit((Object)(object)componentsInChildren[i]) && !(((Object)componentsInChildren[i]).name != "Ember")) { ParticleSystem component = ((Component)componentsInChildren[i]).GetComponent<ParticleSystem>(); if (Object.op_Implicit((Object)(object)component)) { Renderer component2 = ((Component)componentsInChildren[i]).GetComponent<Renderer>(); ManualLogSource log = RunicBarrierPlugin.Log; MainModule main = component.main; log.LogMessage((object)("[RunicBarrier] vfx map: THE AURA'S COLOUR, to match - Ember startColor " + Describe(((MainModule)(ref main)).startColor) + ((Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.sharedMaterial)) ? ("\n material '" + ((Object)component2.sharedMaterial).name + "' shader " + (Object.op_Implicit((Object)(object)component2.sharedMaterial.shader) ? ((Object)component2.sharedMaterial.shader).name : "(none)") + MaterialColours(component2.sharedMaterial)) : ""))); return; } } } RunicBarrierPlugin.Log.LogMessage((object)"[RunicBarrier] vfx map: no 'Ember' child under RunicBarrier's FXPrefab."); } private unsafe static void Summarise(VFXPrefabs which) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) GameObject val = Fetch(which); if ((Object)(object)val == (Object)null) { RunicBarrierPlugin.Log.LogMessage((object)("[RunicBarrier] vfx map, also: " + ((object)(*(VFXPrefabs*)(&which))/*cast due to .constrained prefix*/).ToString() + " NOT IN CACHE")); return; } Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true); string text = ""; for (int i = 0; i < componentsInChildren.Length; i++) { if (Object.op_Implicit((Object)(object)componentsInChildren[i]) && (Object)(object)componentsInChildren[i] != (Object)(object)val.transform) { text = text + ((text.Length > 0) ? ", " : "") + ((Object)componentsInChildren[i]).name; } } RunicBarrierPlugin.Log.LogMessage((object)("[RunicBarrier] vfx map, also: " + ((object)(*(VFXPrefabs*)(&which))/*cast due to .constrained prefix*/).ToString() + " - " + componentsInChildren.Length + " transform(s)" + ((text.Length > 0) ? (", children: " + text) : ", no children"))); } private static void Report(string label, Transform root) { //IL_00c7: 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_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_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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) string text = "[RunicBarrier] vfx map, " + label + ": root '" + ((Object)root).name + "'"; Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); text = text + ", " + componentsInChildren.Length + " transform(s)"; foreach (Transform val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val)) { string text2 = PathOf(val, root); string[] obj = new string[8] { text, "\n ", (text2.Length == 0) ? "<root>" : text2, ((Component)val).gameObject.activeSelf ? "" : " [INACTIVE]", " | localPos=", null, null, null }; Vector3 val2 = val.localPosition; obj[5] = ((Vector3)(ref val2)).ToString("F2"); obj[6] = " | localScale="; val2 = val.localScale; obj[7] = ((Vector3)(ref val2)).ToString("F2"); text = string.Concat(obj); text = text + "\n components: " + Components(val); ParticleSystem component = ((Component)val).GetComponent<ParticleSystem>(); if (Object.op_Implicit((Object)(object)component)) { MainModule main = component.main; EmissionModule emission = component.emission; string[] obj2 = new string[21] { text, "\n particles: loop=", ((MainModule)(ref main)).loop.ToString(), " duration=", ((MainModule)(ref main)).duration.ToString("F2"), " lifetime=", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; MinMaxCurve val3 = ((MainModule)(ref main)).startLifetime; obj2[6] = ((MinMaxCurve)(ref val3)).constant.ToString("F2"); obj2[7] = " startSize="; val3 = ((MainModule)(ref main)).startSize; obj2[8] = ((MinMaxCurve)(ref val3)).constant.ToString("F2"); obj2[9] = " startSpeed="; val3 = ((MainModule)(ref main)).startSpeed; obj2[10] = ((MinMaxCurve)(ref val3)).constant.ToString("F2"); obj2[11] = " max="; obj2[12] = ((MainModule)(ref main)).maxParticles.ToString(); obj2[13] = " rate="; obj2[14] = ((EmissionModule)(ref emission)).rateOverTimeMultiplier.ToString("F1"); obj2[15] = " bursts="; obj2[16] = ((EmissionModule)(ref emission)).burstCount.ToString(); obj2[17] = " space="; obj2[18] = ((object)((MainModule)(ref main)).simulationSpace/*cast due to .constrained prefix*/).ToString(); obj2[19] = "\n startColor: "; obj2[20] = Describe(((MainModule)(ref main)).startColor); text = string.Concat(obj2); } Renderer component2 = ((Component)val).GetComponent<Renderer>(); if (Object.op_Implicit((Object)(object)component2)) { ParticleSystemRenderer val4 = (ParticleSystemRenderer)(object)((component2 is ParticleSystemRenderer) ? component2 : null); text = text + "\n renderer: " + ((object)component2).GetType().Name + " enabled=" + component2.enabled + (((Object)(object)val4 != (Object)null) ? (" renderMode=" + ((object)val4.renderMode/*cast due to .constrained prefix*/).ToString() + " mesh=" + (Object.op_Implicit((Object)(object)val4.mesh) ? ((Object)val4.mesh).name : "(none)")) : "") + "\n material: " + (Object.op_Implicit((Object)(object)component2.sharedMaterial) ? ("'" + ((Object)component2.sharedMaterial).name + "' shader " + (Object.op_Implicit((Object)(object)component2.sharedMaterial.shader) ? ((Object)component2.sharedMaterial.shader).name : "(none)") + " tex=" + TextureName(component2.sharedMaterial) + MaterialColours(component2.sharedMaterial)) : "(none)"); } Light component3 = ((Component)val).GetComponent<Light>(); if (Object.op_Implicit((Object)(object)component3)) { text = text + "\n light: " + ((object)component3.type/*cast due to .constrained prefix*/).ToString() + " colour=" + Hex(component3.color) + " range=" + component3.range.ToString("F2") + " intensity=" + component3.intensity.ToString("F2"); } } } RunicBarrierPlugin.Log.LogMessage((object)text); } private static string TextureName(Material m) { try { if (m.HasProperty("_MainTex") && Object.op_Implicit((Object)(object)m.GetTexture("_MainTex"))) { return ((Object)m.GetTexture("_MainTex")).name; } } catch (Exception) { } return "(none)"; } private static string MaterialColours(Material m) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) string[] array = new string[5] { "_Color", "_TintColor", "_EmissionColor", "_RimColor", "_SpecColor" }; string text = ""; for (int i = 0; i < array.Length; i++) { try { if (m.HasProperty(array[i])) { text = text + "\n " + array[i] + " = " + Hex(m.GetColor(array[i])); } } catch (Exception) { } } return text; } private static string Describe(MinMaxGradient g) { //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_001e: Expected I4, but got Unknown //IL_002a: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) ParticleSystemGradientMode mode = ((MinMaxGradient)(ref g)).mode; return (int)mode switch { 0 => "Color " + Hex(((MinMaxGradient)(ref g)).color), 2 => "TwoColors " + Hex(((MinMaxGradient)(ref g)).colorMin) + " .. " + Hex(((MinMaxGradient)(ref g)).colorMax), 1 => "Gradient (" + ((((MinMaxGradient)(ref g)).gradient != null) ? (((MinMaxGradient)(ref g)).gradient.colorKeys.Length + " keys") : "null") + ")", 3 => "TwoGradients", _ => ((object)((MinMaxGradient)(ref g)).mode/*cast due to .constrained prefix*/).ToString(), }; } private static string Hex(Color c) { //IL_0011: 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_005d: Unknown result type (might be due to invalid IL or missing references) return "#" + Mathf.RoundToInt(Mathf.Clamp01(c.r) * 255f).ToString("X2") + Mathf.RoundToInt(Mathf.Clamp01(c.g) * 255f).ToString("X2") + Mathf.RoundToInt(Mathf.Clamp01(c.b) * 255f).ToString("X2") + " a=" + c.a.ToString("F2") + " (" + c.r.ToString("F2") + "," + c.g.ToString("F2") + "," + c.b.ToString("F2") + ")"; } private static string Components(Transform t) { Component[] components = ((Component)t).GetComponents<Component>(); string text = ""; bool flag = false; bool flag2 = false; foreach (Component val in components) { string text2 = (Object.op_Implicit((Object)(object)val) ? ((object)val).GetType().Name : "(missing script)"); switch (text2) { case "VFXParticlesOnRenderer": case "VFXParticlesOnVisuals": case "VFXParticlesOnTransform": case "VFXParticlesOnChar": case "VFXPositionOnChar": case "VFXFollowCharBone": flag = true; break; } if (text2 == "VFXSystem" && (Object)(object)t.parent != (Object)null) { flag2 = true; } text = text + ((text.Length > 0) ? ", " : "") + text2; } return text + (flag ? " <<< CHARBOUND" : "") + (flag2 ? " <<< NESTED VFXSYSTEM" : ""); } private static string PathOf(Transform t, Transform root) { if ((Object)(object)t == (Object)(object)root) { return ""; } string text = ((Object)t).name; Transform parent = t.parent; while (Object.op_Implicit((Object)(object)parent) && (Object)(object)parent != (Object)(object)root) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } static VFXMap() { VFXPrefabs[] array = new VFXPrefabs[7]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); AlsoSummarise = (VFXPrefabs[])(object)array; } } [BepInPlugin("com.wrango.runicbarrier", "Runic Barrier", "1.0.2")] public class RunicBarrierPlugin : BaseUnityPlugin { internal enum Tier { None, Normal, Amplified } public const string GUID = "com.wrango.runicbarrier"; public const string NAME = "Runic Barrier"; public const string VERSION = "1.0.2"; internal static ManualLogSource Log; internal static RunicBarrierPlugin Instance; private string _mitigationSig; private static readonly bool DIAG = false; private const bool APPLY_MANA_REDUCTION = true; private const string IMPACT_SOUNDS = "CS_GolemShielded_ShieldImpact_01,CS_GolemShielded_ShieldImpact_02,CS_GolemShielded_ShieldImpact_03,CS_GolemShielded_ShieldImpact_04"; private const float PITCH_MIN = 1f; private const float PITCH_MAX = 1f; private const float VOLUME_MIN = 1f; private const float VOLUME_MAX = 1f; private const ProjectilePrefabs SPARK_PROJECTILE = (ProjectilePrefabs)0; private const float SPARK_LIFESPAN = 0f; private const float SPARK_FORCE = 0f; private const float SPARK_SCALE = 1f; private const string SPARK_HIDE_EMITTERS = "ProjectileFX"; private const BlastPrefabs SPARK_BLAST = (BlastPrefabs)63; private const float SPARK_BLAST_LIFESPAN = 5f; private const float SPARK_BLAST_SCALE = 0.07f; private Sounds[] _sounds = (Sounds[])(object)new Sounds[0]; private int _lastIndex = -1; private readonly Dictionary<Sounds, int> _soundTally = new Dictionary<Sounds, int>(); internal static int AbsorbFrame = -1; internal static int AbsorbVictimId; internal static float AbsorbTook; internal static bool LogHits; private static Harmony _harmony; private static int _cueFrame = -1; private bool _hurtboxLogged; private static int _awaitingPointFrame = -1; private static int _awaitingPointHit; private static string _awaitingPointSrc = ""; private const float CUE_HOLD_SECONDS = 8f; private readonly Dictionary<int, UnityAction<Object, DamageList>> _subs = new Dictionary<int, UnityAction<Object, DamageList>>(); private Character _localPlayer; private float _nextScan; private float _manaSpent; private float _healthLet; private float _negated; private int _hits; private int _observed; private bool _wardWasUp; private static FieldInfo _manaField; private static bool _manaFieldResolved; internal const string STATUS_ID = "RunicBarrier"; internal const string STATUS_ID_AMPLIFIED = "RunicBarrierAmplified"; private const float HEALTH_SHARE = 0.6f; private const float MANA_SHARE = 0.6f; private const float HEALTH_SHARE_AMPLIFIED = 0.5f; private const float MANA_SHARE_AMPLIFIED = 0.5f; private readonly Dictionary<int, Tier> _allyWard = new Dictionary<int, Tier>(); private static bool ResolveManaField(CharacterStats stats) { if (_manaFieldResolved) { return _manaField != null; } _manaFieldResolved = true; BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; float currentMana = stats.CurrentMana; Type type = ((object)stats).GetType(); List<string> list = new List<string>(); FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType != typeof(float)) { continue; } float num; try { num = (float)fieldInfo.GetValue(stats); } catch (Exception) { continue; } float num2 = num - currentMana; if (num2 < 0f) { num2 = 0f - num2; } if (!(num2 > 0.0001f)) { list.Add(fieldInfo.Name); if (fieldInfo.Name == "m_mana") { _manaField = fieldInfo; } } } if (_manaField == null && list.Count == 1) { _manaField = type.GetField(list[0], bindingAttr); } if (_manaField != null) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] mana field = " + _manaField.Name + " (candidates: " + string.Join(", ", list.ToArray()) + ")")); } else { Log.LogError((object)(Stamp() + " [RunicBarrier] COULD NOT RESOLVE the mana backing field. Candidates matching CurrentMana=" + currentMana.ToString("F2") + ": " + string.Join(", ", list.ToArray()) + ". The ward is disabled - it must never take damage it cannot charge for.")); } return _manaField != null; } private static string Stamp() { return DateTime.Now.ToString("HH:mm:ss.fff"); } internal void Awake() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Instance = this; Log.LogMessage((object)(Stamp() + " [RunicBarrier 1.0.2] loaded, WARD model. split=" + 0.6f.ToString("0.##") + "/" + 0.6f.ToString("0.##") + " amplified=" + 0.5f.ToString("0.##") + "/" + 0.5f.ToString("0.##") + " (fixed) ApplyManaReduction=" + true + " Spark=" + ((object)(ProjectilePrefabs)0/*cast due to .constrained prefix*/).ToString())); LogHits = DIAG; InstallHitPointHook(); ParseImpactSounds(); } internal void Update() { if (Object.op_Implicit((Object)(object)_localPlayer) && _localPlayer.IsLocalPlayer) { TrackWardSession(_localPlayer); } CollapseAtZeroMana(); if (Time.time < _nextScan) { return; } _nextScan = Time.time + 2f; VFXTrim.TryOnce(); if ((Object)(object)CharacterManager.Instance == (Object)null) { return; } List<int> list = new List<int>(); foreach (Character value in CharacterManager.Instance.Characters.Values) { if (!Object.op_Implicit((Object)(object)value) || value.IsAI) { continue; } int instanceID = ((Object)value).GetInstanceID(); list.Add(instanceID); if (value.IsLocalPlayer) { _localPlayer = value; } if (value.IsLocalPlayer) { LogMitigation(value); } else { LogAllyWard(value, instanceID); } if (!_subs.ContainsKey(instanceID)) { Character victim = value; UnityAction<Object, DamageList> val = delegate(Object src, DamageList dmg) { OnHit(victim, src, dmg); }; value.OnHitPreResistance = (UnityAction<Object, DamageList>)(object)Delegate.Combine((Delegate?)(object)value.OnHitPreResistance, (Delegate?)(object)val); _subs.Add(instanceID, val); Log.LogMessage((object)(Stamp() + " [RunicBarrier] watching " + Describe(value))); LogHurtbox(value); } } List<int> list2 = new List<int>(); foreach (int key in _subs.Keys) { if (!list.Contains(key)) { list2.Add(key); } } foreach (int item in list2) { _subs.Remove(item); } } private void ParseImpactSounds() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0066: Unknown result type (might be due to invalid IL or missing references) try { List<Sounds> list = new List<Sounds>(); List<string> list2 = new List<string>(); string text = "CS_GolemShielded_ShieldImpact_01,CS_GolemShielded_ShieldImpact_02,CS_GolemShielded_ShieldImpact_03,CS_GolemShielded_ShieldImpact_04"; if (!string.IsNullOrEmpty(text)) { string[] array = text.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0) { continue; } try { Sounds val = (Sounds)Enum.Parse(typeof(Sounds), text2, ignoreCase: true); if ((int)val != 0) { list.Add(val); } } catch (Exception) { list2.Add(text2); } } } _sounds = list.ToArray(); if (list2.Count > 0) { Log.LogError((object)(Stamp() + " [RunicBarrier] these ImpactSounds are not valid sound names and were skipped: " + string.Join(", ", list2.ToArray()) + ". Copy them exactly from the ListSoundsMatching output.")); } Log.LogMessage((object)(Stamp() + " [RunicBarrier] impact sounds: " + _sounds.Length + ((_sounds.Length == 0) ? " (silent)" : " in rotation"))); } catch (Exception ex2) { Log.LogError((object)(Stamp() + " [RunicBarrier] could not parse ImpactSounds: " + ex2)); _sounds = (Sounds[])(object)new Sounds[0]; } } private unsafe string PlayImpactSound(Transform at) { //IL_0070: 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_008c: 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_00a9: Unknown result type (might be due to invalid IL or missing references) try { if (_sounds.Length == 0 || (Object)(object)Global.AudioManager == (Object)null || !Object.op_Implicit((Object)(object)at)) { return null; } int num; if (_sounds.Length > 1 && _lastIndex >= 0) { num = Random.Range(0, _sounds.Length - 1); if (num >= _lastIndex) { num++; } } else { num = Random.Range(0, _sounds.Length); } Sounds val = _sounds[num]; _lastIndex = num; if ((int)val == 0) { return "(NONE in the list)"; } _soundTally.TryGetValue(val, out var value); _soundTally[val] = value + 1; Global.AudioManager.PlaySoundAndFollow(val, at, 0f, 1f, 1f, 1f, 1f); return ((object)(*(Sounds*)(&val))/*cast due to .constrained prefix*/).ToString(); } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] impact sound failed: " + ex)); return "(threw)"; } } internal static Tier TierOf(Character c) { if (!Object.op_Implicit((Object)(object)c)) { return Tier.None; } StatusEffectManager statusEffectMngr = c.StatusEffectMngr; if ((Object)(object)statusEffectMngr != (Object)null) { if (statusEffectMngr.HasStatusEffect("RunicBarrierAmplified")) { return Tier.Amplified; } if (statusEffectMngr.HasStatusEffect("RunicBarrier")) { return Tier.Normal; } } return Tier.None; } private void SharesFor(Tier tier, out float hShare, out float mShare) { if (tier == Tier.Amplified) { hShare = 0.5f; mShare = 0.5f; } else { hShare = 0.6f; mShare = 0.6f; } } private void TrackWardSession(Character c) { try { if (Object.op_Implicit((Object)(object)c) && c.IsLocalPlayer) { bool flag = TierOf(c) != Tier.None; if (flag && !_wardWasUp) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] ward session started")); } else if (!flag && _wardWasUp) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] ward ended - dismissed, expired or collapsed; this edge does not say which")); } _wardWasUp = flag; } } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] ward session tracking threw: " + ex)); } } private void LogMitigation(Character c) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)c == (Object)null || (Object)(object)c.Stats == (Object)null) { return; } float[] damageProtection = c.Stats.DamageProtection; float[] damageResistance = c.Stats.DamageResistance; if (damageProtection == null || damageResistance == null) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] mitigation: arrays unavailable")); return; } string text = ""; for (int i = 0; i < damageProtection.Length; i++) { string text2 = ((i < 9) ? ((object)(Types)i/*cast due to .constrained prefix*/).ToString() : ("?" + i)); text = text + " " + text2 + "=" + damageProtection[i].ToString("F2") + "/" + (damageResistance[i] * 100f).ToString("F0") + "%"; } float num = c.Stats.GetFinalManaConsumption((Tag[])null, 100f) / 100f; float manaRegen = c.Stats.ManaRegen; string text3 = text + "|" + c.Stats.GetBarrier().ToString("F2") + "|" + num.ToString("F3") + "|" + manaRegen.ToString("F3"); if (!(text3 == _mitigationSig)) { bool flag = _mitigationSig != null; _mitigationSig = text3; Log.LogMessage((object)(Stamp() + " [RunicBarrier] mitigation of " + c.Name + (flag ? " CHANGED" : "") + " | flat/resist by type:" + text + " | Barrier=" + c.Stats.GetBarrier().ToString("F2") + " | manaMod x" + num.ToString("F3") + ((num > 1.001f) ? " (a PENALTY, not a reduction)" : "") + " | manaRegenStat " + manaRegen.ToString("F3") + "/s" + ((manaRegen < -0.001f) ? " (rate negative; food may still carry it positive)" : ((manaRegen < 0.001f) ? " (rate suspended)" : "")))); } } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] mitigation dump threw: " + ex)); } } private float ManaBillBase(Character victim, DamageList dmg, float mShare, out float flatUsed) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected I4, but got Unknown //IL_0084: 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_0094: Expected I4, but got Unknown flatUsed = 0f; if ((Object)(object)victim == (Object)null || (Object)(object)victim.Stats == (Object)null) { return dmg.TotalDamage * mShare; } float[] damageProtection = victim.Stats.DamageProtection; float[] damageResistance = victim.Stats.DamageResistance; if (damageProtection == null || damageResistance == null) { return dmg.TotalDamage * mShare; } float barrier = victim.Stats.GetBarrier(); int num = -1; if (barrier > 0f) { float num2 = 0f; float num3 = 0f; for (int i = 0; i < dmg.Count; i++) { DamageType val = dmg[i]; if ((int)val.Type != 0) { int num4 = (int)val.Type; if (num4 >= 0 && num4 < damageResistance.Length && (num < 0 || damageResistance[num4] < num2 || (damageResistance[num4] == num2 && val.Damage > num3))) { num = num4; num2 = damageResistance[num4]; num3 = val.Damage; } } } } float num5 = 0f; for (int j = 0; j < dmg.Count; j++) { DamageType obj = dmg[j]; int num6 = (int)obj.Type; float num7 = ((num6 >= 0 && num6 < damageProtection.Length) ? damageProtection[num6] : 0f); if (num6 == num) { num7 += barrier; } float num8 = obj.Damage * mShare; float num9 = num8 - num7; if (num9 < 0f) { num9 = 0f; } flatUsed += num8 - num9; num5 += num9; } return num5; } private void Collapse(Character victim) { try { if (Object.op_Implicit((Object)(object)victim) && !((Object)(object)victim.StatusEffectMngr == (Object)null)) { bool flag = false; if (victim.StatusEffectMngr.HasStatusEffect("RunicBarrier")) { victim.StatusEffectMngr.CleanseStatusEffect("RunicBarrier"); flag = true; } if (victim.StatusEffectMngr.HasStatusEffect("RunicBarrierAmplified")) { victim.StatusEffectMngr.CleanseStatusEffect("RunicBarrierAmplified"); flag = true; } Log.LogMessage((object)(Stamp() + " [RunicBarrier] WARD COLLAPSED on " + victim.Name + " - out of Mana" + (flag ? ", status removed" : ", no status was present"))); } } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] collapse threw: " + ex)); } } private void CollapseAtZeroMana() { if (Object.op_Implicit((Object)(object)NetworkLevelLoader.Instance) && !NetworkLevelLoader.Instance.IsOverallLoadingDone) { return; } CharacterManager instance = CharacterManager.Instance; if ((Object)(object)instance == (Object)null) { return; } foreach (Character value in instance.Characters.Values) { if (Object.op_Implicit((Object)(object)value) && value.IsLocalPlayer && Object.op_Implicit((Object)(object)value.Stats) && !(value.Stats.CurrentMana > 0f) && TierOf(value) != Tier.None) { Collapse(value); } } } internal static bool WardIsUp(Character c) { return TierOf(c) != Tier.None; } private void LogAllyWard(Character c, int id) { try { if (!((Object)(object)c == (Object)null)) { Tier tier = TierOf(c); if (!_allyWard.TryGetValue(id, out var value) || value != tier) { bool flag = _allyWard.ContainsKey(id); _allyWard[id] = tier; Log.LogMessage((object)(Stamp() + " [RunicBarrier] ally " + c.Name + ": ward " + ((tier == Tier.None) ? "None" : tier.ToString()) + (flag ? " (changed - as THIS client sees it)" : " (first sighting)"))); } } } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] ally ward watch threw: " + ex)); } } private void LogObserved(Character victim, Object src, DamageList dmg) { try { string text = ""; for (int i = 0; i < dmg.Count; i++) { DamageType val = dmg[i]; if (i > 0) { text += "/"; } text = text + ((object)Unsafe.As<Types, Types>(ref val.Type)/*cast due to .constrained prefix*/).ToString() + ":" + val.Damage.ToString("F1"); } float before = (Object.op_Implicit((Object)(object)victim.Stats) ? victim.Stats.CurrentHealth : (-1f)); _observed++; int observed = _observed; string text2 = Stamp() + " [RunicBarrier] OBSERVED #" + observed + " on " + (victim.Name ?? "?") + " (NOT ours - nothing touched) | src=" + (Object.op_Implicit(src) ? ((object)src).GetType().Name : "null") + " | entries=" + dmg.Count + " [" + text + "] raw=" + dmg.TotalDamage.ToString("F2") + " | health before=" + before.ToString("F2"); Log.LogMessage((object)text2); ((MonoBehaviour)this).StartCoroutine(ReportObservedHealth(victim, before, observed)); } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] observer threw: " + ex)); } } private IEnumerator ReportObservedHealth(Character victim, float before, int n) { yield return null; float afterOne = ((Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)victim.Stats)) ? victim.Stats.CurrentHealth : (-1f)); yield return (object)new WaitForSeconds(0.25f); float num = ((Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)victim.Stats)) ? victim.Stats.CurrentHealth : (-1f)); Log.LogMessage((object)(Stamp() + " [RunicBarrier] OBSERVED #" + n + " health " + before.ToString("F2") + " -> " + afterOne.ToString("F2") + " (1 frame) -> " + num.ToString("F2") + " (0.25s) | TOOK " + (before - num).ToString("F2") + " as this client sees it")); } private IEnumerator ReportOwnHealth(Character victim, float before, int hit) { yield return null; yield return (object)new WaitForSeconds(0.25f); float num = ((Object.op_Implicit((Object)(object)victim) && Object.op_Implicit((Object)(object)victim.Stats)) ? victim.Stats.CurrentHealth : (-1f)); Log.LogMessage((object)(Stamp() + " [RunicBarrier] SPLIT #" + hit + " health " + before.ToString("F2") + " -> " + num.ToString("F2") + " (0.25s) | TOOK " + (before - num).ToString("F2") + " as OUR client sees it")); } private void LogSoundTally() { //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) if (_soundTally.Count == 0) { return; } int num = 0; foreach (KeyValuePair<Sounds, int> item in _soundTally) { num += item.Value; } Log.LogMessage((object)(Stamp() + " [RunicBarrier] sound tally over " + num + " plays:")); foreach (KeyValuePair<Sounds, int> item2 in _soundTally) { Log.LogMessage((object)(" " + ((object)item2.Key/*cast due to .constrained prefix*/).ToString() + " x" + item2.Value + " (" + (100f * (float)item2.Value / (float)num).ToString("F0") + "%)")); } if (_soundTally.Count < _sounds.Length) { Log.LogMessage((object)(" NOTE: only " + _soundTally.Count + " of " + _sounds.Length + " configured sounds were ever picked.")); } } private void OnHit(Character victim, Object src, DamageList dmg) { //IL_02ea: Unknown result type (might be due to invalid IL or missing references) try { if (!Object.op_Implicit((Object)(object)victim) || dmg == null) { return; } if (!victim.IsLocalPlayer) { if (DIAG) { LogObserved(victim, src, dmg); } return; } string text = (Object.op_Implicit(src) ? ((object)src).GetType().Name : "null"); string text2 = ""; for (int i = 0; i < dmg.Count; i++) { DamageType val = dmg[i]; if (i > 0) { text2 += "/"; } text2 = text2 + ((object)Unsafe.As<Types, Types>(ref val.Type)/*cast due to .constrained prefix*/).ToString() + ":" + val.Damage.ToString("F1"); } string text3 = "entries=" + dmg.Count + " [" + text2 + "] raw=" + dmg.TotalDamage.ToString("F2"); Tier tier = TierOf(victim); if (tier == Tier.None) { if (DIAG) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] ward DOWN, hit passes whole src=" + text + " " + text3)); } return; } float before = (Object.op_Implicit((Object)(object)victim.Stats) ? victim.Stats.CurrentHealth : (-1f)); float totalDamage = dmg.TotalDamage; if (totalDamage <= 0f) { return; } SharesFor(tier, out var hShare, out var mShare); float num = Mathf.Max(0f, 1f - hShare - mShare); if (mShare <= 0f) { if (DIAG) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] Mana share is 0, nothing to charge src=" + text + " " + text3)); } } else { if (!ResolveManaField(victim.Stats)) { return; } LogMitigation(victim); float flatUsed; float num2 = ManaBillBase(victim, dmg, mShare, out flatUsed); float num3 = num2; num3 = victim.Stats.GetFinalManaConsumption((Tag[])null, num2); float currentMana = victim.Stats.CurrentMana; float num4 = 1f; bool flag = false; if (num3 > currentMana) { num4 = ((num3 > 0f) ? Mathf.Clamp01(currentMana / num3) : 0f); flag = true; } float num5 = num3 * num4; float num6 = mShare * num4; float num7 = mShare * (1f - num4); float num8 = hShare + num7; List<DamageType> list = new List<DamageType>(); for (int j = 0; j < dmg.Count; j++) { DamageType val2 = dmg[j]; val2.Damage *= num8; if (val2.Damage <= 0.001f) { list.Add(val2); } } foreach (DamageType item in list) { dmg.Remove(item.Type); } _manaField.SetValue(victim.Stats, currentMana - num5); _hits++; _manaSpent += num5; _healthLet += totalDamage * num8; _negated += totalDamage * num; if (_awaitingPointFrame >= 0) { Log.LogWarning((object)(Stamp() + " [RunicBarrier] split #" + _awaitingPointHit + " (" + _awaitingPointSrc + ") never received a hit point - no impact sound and no spark for it.")); } if (DIAG) { ((MonoBehaviour)this).StartCoroutine(ReportOwnHealth(victim, before, _hits)); } _awaitingPointFrame = Time.frameCount; _awaitingPointHit = _hits; _awaitingPointSrc = text; AbsorbFrame = Time.frameCount; AbsorbVictimId = ((Object)victim).GetInstanceID(); AbsorbTook = totalDamage * num6; if (flag) { Collapse(victim); } Log.LogMessage((object)(Stamp() + " [RunicBarrier] " + (flag ? "SPLIT+COLLAPSE #" : "SPLIT #") + _hits + " src=" + text + " tier=" + tier.ToString() + " (" + hShare.ToString("0.##") + "/" + mShare.ToString("0.##") + " = " + (hShare + mShare).ToString("0.##") + "x raw) | raw=" + totalDamage.ToString("F2") + " -> health=" + (totalDamage * num8).ToString("F2") + " mana=" + (totalDamage * num6).ToString("F2") + " negated=" + (totalDamage * num).ToString("F2") + " | cost=" + num3.ToString("F2") + " (flat -" + flatUsed.ToString("F2") + ((num3 <= 0.001f) ? ", FREE" : "") + ") spent=" + num5.ToString("F2") + ((num3 < num2 - 0.01f) ? (" (reduced from " + num2.ToString("F2") + ")") : "") + " | mana " + currentMana.ToString("F2") + " -> " + victim.Stats.CurrentMana.ToString("F2") + " | " + text3 + " | list now=" + dmg.TotalDamage.ToString("F2") + (flag ? (" | WARD DOWN, " + (totalDamage * num7).ToString("F2") + " fell back to Health") : "") + " | totals mana=" + _manaSpent.ToString("F1") + " healthShare=" + _healthLet.ToString("F1") + " negated=" + _negated.ToString("F1"))); } } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] handler threw: " + ex)); } } private void InstallHitPointHook() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown try { Type[] array = new Type[9] { typeof(Weapon), typeof(float), typeof(DamageList), typeof(Vector3), typeof(Vector3), typeof(float), typeof(float), typeof(Character), typeof(float) }; MethodInfo methodInfo = AccessTools.Method(typeof(Character), "OnReceiveHit", array, (Type[])null); if (methodInfo == null) { Log.LogError((object)(Stamp() + " [RunicBarrier] OnReceiveHit not found with that signature - no hit point, so the spark cannot fire.")); return; } _harmony = new Harmony("com.wrango.runicbarrier"); _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(RunicBarrierPlugin).GetMethod("OnReceiveHitPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.PatchAll(typeof(Projectile_Shoot_KeepAlive)); _harmony.PatchAll(typeof(Item_Start_NameSync)); Log.LogMessage((object)(Stamp() + " [RunicBarrier] OnReceiveHit hook installed.")); } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] could not install the hook: " + ex)); } } private static void OnReceiveHitPrefix(Character __instance, Weapon _weapon, float _damage, DamageList _damageList, Vector3 _hitDir, Vector3 _hitPoint, float _angle, float _angleDir, Character _dealerChar, float _knockBack) { //IL_00aa: 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_0229: Unknown result type (might be due to invalid IL or missing references) try { if (!Object.op_Implicit((Object)(object)__instance) || __instance.IsAI) { return; } bool flag = __instance.IsLocalPlayer && Time.frameCount == AbsorbFrame && ((Object)__instance).GetInstanceID() == AbsorbVictimId; bool flag2 = !__instance.IsLocalPlayer && WardIsUp(__instance); if (!flag && !flag2 && !LogHits) { return; } string text = null; string text2 = null; string text3 = null; if ((flag || flag2) && (Object)(object)Instance != (Object)null) { if (flag) { _awaitingPointFrame = -1; } if (Time.frameCount == _cueFrame) { text = "(suppressed, same frame)"; } else { _cueFrame = Time.frameCount; GameObject val = Spark.CreateCue(__instance, _hitPoint, _hitDir, 8f); text2 = Instance.PlayImpactSound(val.transform); text = Spark.Fire(val, __instance, (ProjectilePrefabs)0, 0f, 0f, 1f, "ProjectileFX"); text3 = SparkBlast.Fire(val, __instance, (BlastPrefabs)63, 5f, 0.07f, "ProjectileFX"); } } Log.LogMessage((object)(Stamp() + " [RunicBarrier] OnReceiveHit" + (flag ? (" *** same frame as a split taking " + AbsorbTook.ToString("F2") + " ***") : "") + (flag2 ? (" *** ALLY " + (__instance.Name ?? "?") + ", ward up - cue only, no split on this client ***") : "") + ((text2 == null) ? "" : (" | sound=" + text2)) + ((text == null) ? "" : (" | spark=" + text)) + ((text3 == null) ? "" : (" | blast=" + text3)) + " | _damage=" + _damage.ToString("F2") + " | list=" + ((_damageList == null) ? "null" : (_damageList.Count + " entries total=" + _damageList.TotalDamage.ToString("F2"))) + " | " + Offset(__instance, _hitPoint) + " | _hitPoint=" + ((Vector3)(ref _hitPoint)).ToString("F2") + " | _hitDir=" + ((Vector3)(ref _hitDir)).ToString("F2") + " | _knockBack=" + _knockBack.ToString("F2") + " | dealer=" + (Object.op_Implicit((Object)(object)_dealerChar) ? _dealerChar.Name : "null"))); } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] OnReceiveHit prefix threw: " + ex)); } } private static string Offset(Character victim, Vector3 hitPoint) { //IL_0014: 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_001b: 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_002c: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)victim)) { return "offset=(no character)"; } Vector3 val = ((Component)victim).transform.InverseTransformPoint(hitPoint); Vector3 val2 = hitPoint - ((Component)victim).transform.position; float magnitude = ((Vector3)(ref val2)).magnitude; return "offset r=" + val.x.ToString("F2") + " u=" + val.y.ToString("F2") + " f=" + val.z.ToString("F2") + " dist=" + magnitude.ToString("F2"); } private void LogHurtbox(Character c) { //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_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_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_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_014f: Unknown result type (might be due to invalid IL or missing references) try { if (_hurtboxLogged || !Object.op_Implicit((Object)(object)c)) { return; } _hurtboxLogged = true; Collider[] componentsInChildren = ((Component)c).GetComponentsInChildren<Collider>(true); string[] obj = new string[7] { Stamp(), " [RunicBarrier] hurtbox of ", c.Name, ": ", componentsInChildren.Length.ToString(), " collider(s), root at ", null }; Vector3 val = ((Component)c).transform.position; obj[6] = ((Vector3)(ref val)).ToString("F2"); string text = string.Concat(obj); foreach (Collider val2 in componentsInChildren) { if (Object.op_Implicit((Object)(object)val2)) { Bounds bounds = val2.bounds; string[] obj2 = new string[12] { text, "\n ", ((object)val2).GetType().Name, " '", ((Object)val2).name, "'", val2.enabled ? "" : " (disabled)", val2.isTrigger ? " (trigger)" : "", " | extents=", null, null, null }; val = ((Bounds)(ref bounds)).extents; obj2[9] = ((Vector3)(ref val)).ToString("F2"); obj2[10] = " | centre offset from root="; val = ((Component)c).transform.InverseTransformPoint(((Bounds)(ref bounds)).center); obj2[11] = ((Vector3)(ref val)).ToString("F2"); text = string.Concat(obj2); } } Log.LogMessage((object)text); } catch (Exception ex) { Log.LogError((object)(Stamp() + " [RunicBarrier] hurtbox dump failed: " + ex)); } } private static string Describe(Character c) { if (!Object.op_Implicit((Object)(object)c)) { return "<null>"; } return c.Name + "(local=" + c.IsLocalPlayer + ",id=" + ((Object)c).GetInstanceID() + ")"; } internal void OnDestroy() { foreach (KeyValuePair<int, UnityAction<Object, DamageList>> sub in _subs) { if ((Object)(object)CharacterManager.Instance == (Object)null) { break; } foreach (Character value in CharacterManager.Instance.Characters.Values) { if (Object.op_Implicit((Object)(object)value) && ((Object)value).GetInstanceID() == sub.Key) { value.OnHitPreResistance = (UnityAction<Object, DamageList>)(object)Delegate.Remove((Delegate?)(object)value.OnHitPreResistance, (Delegate?)(object)sub.Value); } } } _subs.Clear(); if (_harmony != null) { try { _harmony.UnpatchSelf(); } catch (Exception) { } _harmony = null; } if (_awaitingPointFrame >= 0 && Log != null) { Log.LogWarning((object)(Stamp() + " [RunicBarrier] split #" + _awaitingPointHit + " (" + _awaitingPointSrc + ") never received a hit point - no impact sound and no spark for it.")); _awaitingPointFrame = -1; } LogSoundTally(); if (Log != null) { Log.LogMessage((object)(Stamp() + " [RunicBarrier] unloaded. hits=" + _hits + " mana=" + _manaSpent.ToString("F1") + " healthShare=" + _healthLet.ToString("F1") + " negated=" + _negated.ToString("F1"))); } } } internal static class Spark { internal static GameObject CreateCue(Character victim, Vector3 point, Vector3 hitDir, float holdSeconds) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("RunicBarrierCue"); val.transform.SetParent(((Component)victim).transform, false); val.transform.position = point; if (((Vector3)(ref hitDir)).sqrMagnitude > 0.0001f) { val.transform.rotation = Quaternion.LookRotation(-((Vector3)(ref hitDir)).normalized); } Object.Destroy((Object)(object)val, holdSeconds); return val; } internal unsafe static string Fire(GameObject host, Character victim, ProjectilePrefabs prefab, float lifespan, float force, float scale, string hideEmitters) { //IL_0000: 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_002d: 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_0036: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_009b: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00cd: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //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_0128: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_01f1: 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) try { if ((int)prefab == 0) { return null; } if (!Object.op_Implicit((Object)(object)victim) || !Object.op_Implicit((Object)(object)host)) { return null; } ShootProjectile val = host.AddComponent<ShootProjectile>(); ((SL_Effect)new SL_ShootProjectile { SyncType = (SyncTypes)2, CastPosition = (CastPositionType)0, LocalPositionAdd = Vector3.zero, NoAim = true, TargetType = (TargetTypes)0, TransformName = "SparkTransform", BaseProjectile = prefab, InstantiatedAmount = 1, Lifespan = lifespan, LateShootTime = 0f, Unblockable = false, EffectsOnlyIfHitCharacter = false, EndMode = (EndLifeMode)0, DisableOnHit = true, IgnoreShooterCollision = true, TargetingMode = (TargetMode)0, TargetCountPerProjectile = 1, TargetRange = 0f, AutoTarget = false, AutoTargetMaxAngle = 360f, AutoTargetRange = 0f, ProjectileForce = force, DefenseLength = 0f, DefenseRange = 0f, TrailEnabled = false, TrailTime = 0f, LightIntensityFade = new Vector2(10f, 2f), PointOffset = Vector3.zero, AddDirection = Vector3.zero, AddRotationForce = Vector3.zero, YMagnitudeAffect = 0f, YMagnitudeForce = 0f, CameraAddYDirection = 0f, EffectBehaviour = (EditBehaviours)2, ProjectileEffects = (SL_EffectTransform[])(object)new SL_EffectTransform[0] }).ApplyToComponent<ShootProjectile>(val); ((Shooter)val).Setup((Factions[])(object)new Factions[1], host.transform); Projectile_Shoot_KeepAlive.SparkPending = true; Projectile_Shoot_KeepAlive.PendingScale = scale; Projectile_Shoot_KeepAlive.PendingPoint = host.transform.position; Projectile_Shoot_KeepAlive.PendingCue = host.transform; Projectile_Shoot_KeepAlive.PendingHideEmitters = hideEmitters; Projectile_Shoot_KeepAlive.LastDrift = ""; try { ((Effect)val).Affect(victim); } finally { Projectile_Shoot_KeepAlive.SparkPending = false; Projectile_Shoot_KeepAlive.PendingCue = null; } string? text = ((object)(*(ProjectilePrefabs*)(&prefab))/*cast due to .constrained prefix*/).ToString(); Vector3 position = host.transform.position; return text + " at " + ((Vector3)(ref position)).ToString("F1") + ((Projectile_Shoot_KeepAlive.LastDrift.Length > 0) ? (" " + Projectile_Shoot_KeepAlive.LastDrift) : " drift=(postfix did not run)"); } catch (Exception ex) { RunicBarrierPlugin.Log.LogError((object)("[RunicBarrier] spark failed: " + ex)); return "(threw)"; } } internal static void MakeParticlesLocal(Component root) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren.Length; i++) { MainModule main = componentsInChildren[i].main; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; } } internal static string HideEmitters(Component root, string names) { if (string.IsNullOrEmpty(names)) { return ""; } string[] array = names.Split(new char[1] { ',' }); ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true); string text = ""; foreach (ParticleSystem val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val)) { continue; } for (int j = 0; j < array.Length; j++) { string text2 = array[j].Trim(); if (text2.Length != 0 && string.Equals(((Object)val).name, text2, StringComparison.OrdinalIgnoreCase)) { val.Stop(true, (ParticleSystemStopBehavior)0); ((Component)val).gameObject.SetActive(false); text = text + ((text.Length > 0) ? "," : "") + ((Object)val).name; break; } } } return text; } } [HarmonyPatch(typeof(Projectile), "Shoot")] public class Projectile_Shoot_KeepAlive { internal static bool SparkPending; internal static float PendingScale = 1f; internal static Vector3 PendingPoint; internal static Transform PendingCue; internal static string PendingHideEmitters = ""; internal static string LastDrift = ""; private static readonly HashSet<string> Described = new HashSet<string>(); private static readonly FieldRef<Projectile, bool> FirstUpdate = AccessTools.FieldRefAccess<Projectile, bool>("m_firstUpdate"); [HarmonyPostfix] public static void Postfix(Projectile __instance) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0064: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (!SparkPending || !Object.op_Implicit((Object)(object)__instance)) { return; } FirstUpdate.Invoke(__instance) = false; if (!((Component)__instance).gameObject.activeSelf) { ((Component)__instance).gameObject.SetActive(true); } try { ApplyScale(__instance, PendingScale); Describe(__instance, PendingScale); Vector3 position = ((Component)__instance).transform.position; Vector3 val = ((Component)__instance).transform.InverseTransformPoint(PendingPoint); Vector3 val2 = position - PendingPoint; string text = ((Vector3)(ref val2)).magnitude.ToString("F2"); val2 = -val; LastDrift = "drift=" + text + " local=" + ((Vector3)(ref val2)).ToString("F2"); ((Component)__instance).transform.position = PendingPoint; position = PendingPoint; if (Object.op_Implicit((Object)(object)PendingCue)) { ((Component)__instance).gameObject.AddComponent<SparkFollow>().Cue = PendingCue; Spark.MakeParticlesLocal((Component)(object)__instance); string text2 = Spark.HideEmitters((Component)(object)__instance, PendingHideEmitters); if (text2.Length > 0) { LastDrift = LastDrift + " hid=" + text2; } } ((MonoBehaviour)RunicBarrierPlugin.Instance).StartCoroutine(ReportTravel(__instance, PendingCue, ((Object)__instance).GetInstanceID())); } catch (Exception ex) { RunicBarrierPlugin.Log.LogError((object)("[RunicBarrier] spark scale failed: " + ex)); } } private static IEnumerator ReportTravel(Projectile projectile, Transform cue, int id) { yield return null; string afterOne = Gap(projectile, cue); yield return null; yield return null; string text = Gap(projectile, cue); if (afterOne != "0.00" || text != "0.00") { RunicBarrierPlugin.Log.LogMessage((object)("[RunicBarrier] spark " + id + " sits " + afterOne + " from the cue after 1 frame, " + text + " after 3.")); } } private static string Gap(Projectile projectile, Transform cue) { //IL_0022: 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_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) if (!Object.op_Implicit((Object)(object)projectile)) { return "(gone)"; } if (!Object.op_Implicit((Object)(object)cue)) { return "(cue gone)"; } Vector3 val = ((Component)projectile).transform.position - cue.position; return ((Vector3)(ref val)).magnitude.ToString("F2"); } private static void ApplyScale(Projectile projectile, float scale) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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) if (!(scale <= 0f) && !(Math.Abs(scale - 1f) <= 0.001f)) { ParticleSystem[] componentsInChildren = ((Component)projectile).GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren.Length; i++) { MainModule main = componentsInChildren[i].main; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; } ((Component)projectile).transform.localScale = Vector3.one * scale; } } private static void Describe(Projectile projectile, float scale) { //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_00b2: 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_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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0186: 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_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: 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_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) string name = ((Object)((Component)projectile).gameObject).name; if (!Described.Add(name + "@" + scale.ToString("F3"))) { return; } ParticleSystem[] componentsInChildren = ((Component)projectile).GetComponentsInChildren<ParticleSystem>(true); string[] obj = new string[8] { "[RunicBarrier] spark prefab '", name, "' at SparkScale ", scale.ToString("F2"), ": ", componentsInChildren.Length.ToString(), " particle system(s), root scale now ", null }; Vector3 val = ((Component)projectile).transform.localScale; obj[7] = ((Vector3)(ref val)).ToString("F2"); string text = string.Concat(obj); foreach (ParticleSystem val2 in componentsInChildren) { MainModule main = val2.main; string[] obj2 = new string[15] { text, "\n ", Path(((Component)val2).transform, ((Component)projectile).transform), " | scaling=", ((object)((MainModule)(ref main)).scalingMode/*cast due to .constrained prefix*/).ToString(), " | space=", ((object)((MainModule)(ref main)).simulationSpace/*cast due to .constrained prefix*/).ToString(), " | startSize=", null, null, null, null, null, null, null }; MinMaxCurve startSize = ((MainModule)(ref main)).startSize; obj2[8] = ((MinMaxCurve)(ref startSize)).constant.ToString("F2"); obj2[9] = " | localScale="; val = ((Component)val2).transform.localScale; obj2[10] = ((Vector3)(ref val)).ToString("F2"); obj2[11] = " | localPos="; val = ((Component)val2).transform.localPosition; obj2[12] = ((Vector3)(ref val)).ToString("F2"); obj2[13] = " | offsetFromRoot="; val = ((Component)projectile).transform.InverseTransformPoint(((Component)val2).transform.position); obj2[14] = ((Vector3)(ref val)).ToString("F2"); text = string.Concat(obj2); } Renderer[] componentsInChildren2 = ((Component)projectile).GetComponentsInChildren<Renderer>(true); Light[] componentsInChildren3 = ((Component)projectile).GetComponentsInChildren<Light>(true); text = text + "\n renderers=" + componentsInChildren2.Length + " lights=" + componentsInChildren3.Length; foreach (Renderer val3 in componentsInChildren2) { if (Object.op_Implicit((Object)(object)val3)) { string[] obj3 = new string[7] { text, "\n renderer '", Path(((Component)val3).transform, ((Component)projectile).transform), "' | localPos=", null, null, null }; val = ((Component)val3).transform.localPosition; obj3[4] = ((Vector3)(ref val)).ToString("F2"); obj3[5] = " | offsetFromRoot="; val = ((Component)projectile).transform.InverseTransformPoint(((Component)val3).transform.position); obj3[6] = ((Vector3)(ref val)).ToString("F2"); text = string.Concat(obj3); } } RunicBarrierPlugin.Log.LogMessage((object)text); } private static string Path(Transform t, Transform root) { string text = ((Object)t).name; Transform parent = t.parent; while (Object.op_Implicit((Object)(object)parent) && (Object)(object)parent != (Object)(object)root) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal static class SparkBlast { internal unsafe static string Fire(GameObject host, Character victim, BlastPrefabs prefab, float lifespan, float scale, string hideEmitters) { //IL_0000: 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_002d: 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_0036: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00f4: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) try { if ((int)prefab == 0) { return null; } if (!Object.op_Implicit((Object)(object)victim) || !Object.op_Implicit((Object)(object)host)) { return null; } ShootBlast val = host.AddComponent<ShootBlast>(); ((SL_Effect)new SL_ShootBlast { SyncType = (SyncTypes)2, CastPosition = (CastPositionType)0, LocalPositionAdd = Vector3.zero, NoAim = true, TargetType = (TargetTypes)0, TransformName = "SparkBlastTransform", BaseBlast = prefab, Radius = 0.01f, RefreshTime = 0f, BlastLifespan = lifespan, InstantiatedAmount = 1, Interruptible = false, MaxHitTargetCount = 1, AffectHitTargetCenter = false, HitOnShoot = false, IgnoreShooter = true, IgnoreStop = false, NoTargetForwardMultiplier = 1f, ParentToShootTransform = true, UseTargetCharacterPositionType = false, DontPlayHitSound = false, FXIsWorld = false, PlaySounOnRefresh = false, DelayFirstShoot = 0f, PlayFXOnRefresh = false, EffectBehaviour = (EditBehaviours)2, BlastEffects = (SL_EffectTransform[])(object)new SL_EffectTransform[0] }).ApplyToComponent<ShootBlast>(val); ((Shooter)val).Setup((Factions[])(object)new Factions[1], host.transform); ((Effect)val).Affect(victim); Blast[] componentsInChildren = host.GetComponentsInChildren<Blast>(true); string text = ""; foreach (Blast val2 in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val2)) { continue; } Spark.MakeParticlesLocal((Component)(object)val2); string text2 = Spark.HideEmitters((Component)(object)val2, hideEmitters); if (text2.Length > 0) { text = text + " hid=" + text2; } if (scale > 0f && Math.Abs(scale - 1f) > 0.001f) { ParticleSystem[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { MainModule main = componentsInChildren2[j].main; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; } ((Component)val2).transform.localScale = Vector3.one * scale; } } if (componentsInChildren.Length == 0) { text = " (no Blast found under the cue - nothing sized or hidden)"; } return ((object)(*(BlastPrefabs*)(&prefab))/*cast due to .constrained prefix*/).ToString() + " blast x" + componentsInChildren.Length + text; } catch (Exception ex) { RunicBarrierPlugin.Log.LogError((object)("[RunicBarrier] spark blast failed: " + ex)); return "(threw)"; } } } internal class SparkFollow : MonoBehaviour { internal Transform Cue; private void LateUpdate() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Cue)) { Object.Destroy((Object)(object)this); } else { ((Component)this).transform.position = Cue.position; } } } internal static class VFXTrim { private static readonly string[] Statuses = new string[2] { "RunicBarrier", "RunicBarrierAmplified" }; private const string AURA_KEEP = "Ember"; private static readonly string[] AuraDrop = new string[2] { "SphereSmoke", "Cyl" }; private static readonly bool LOOP_AURA = true; private static readonly float AURA_RATE_SCALE = 0.2f; private static readonly float AURA_BURST_SCALE = 0.1f; private static readonly float AURA_CYCLE_SECONDS = 3f; private static readonly float AURA_BURST_PROBABILITY = 0.6f; private static readonly bool AURA_LOCAL_SPACE = false; private static readonly bool RUNES_ENABLED = true; private const VFXPrefabs RUNE_SOURCE = (VFXPrefabs)52; private const string RUNE_CHILD = "Cloud/Runes"; private const string RUNE_NAME = "RunicBarrierRunes"; private static readonly float RUNE_HEIGHT = -0.18f; private static readonly float RUNE_RATE = 3f; private static readonly float RUNE_LIFETIME = 2f; private static readonly bool RUNE_LOCAL_SPACE = true; private static readonly float RUNE_SIZE_SCALE = 1f; private const int MAX_ATTEMPTS = 15; private static bool _statusesDone; private static int _attempts; private static bool _gaveUp; internal static void TryOnce() { if (!_gaveUp && !_statusesDone) { _attempts++; try { _statusesDone = DoStatuses(); } catch (Exception ex) { RunicBarrierPlugin.Log.LogError((object)("[RunicBarrier] vfx trim threw: " + ex)); _gaveUp = true; return; } if (!_statusesDone && _attempts >= 15) { _gaveUp = true; RunicBarrierPlugin.Log.LogWarning((object)("[RunicBarrier] vfx trim gave up after " + _attempts + " attempts - a status never resolved. An untrimmed copy still carries the dome.")); } } } private static bool DoStatuses() { if (ResourcesPrefabManager.Instance == null) { return false; } bool result = true; for (int i = 0; i < Statuses.Length; i++) { StatusEffect statusEffectPrefab = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(Statuses[i]); if (!Object.op_Implicit((Object)(object)statusEffectPrefab)) { result = false; } else if (!Object.op_Implicit((Object)(object)statusEffectPrefab.FXPrefab)) { RunicBarrierPlugin.Log.LogMessage((object)("[RunicBarrier] vfx trim, status '" + Statuses[i] + "': FXPrefab is NULL, FxInstantiation=" + ((object)Unsafe.As<FXInstantiationTypes, FXInstantiationTypes>(ref statusEffectPrefab.FxInstantiation)/*cast due to .constrained prefix*/).ToString() + " - the XML's VFXPrefab did not resolve to a prefab.")); } else { Trim("status '" + Statuses[i] + "'", statusEffectPrefab.FXPrefab); } } return result; } private static void Trim(string label, Transform root) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: 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_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_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_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) string text = "[RunicBarrier] vfx trim, " + label + ": root '" + ((Object)root).name + "'"; MinMaxGradient startColor = default(MinMaxGradient); ((MinMaxGradient)(ref startColor))..ctor(Color.white); bool haveColour = false; ParticleSystemRenderer component = ((Component)root).GetComponent<ParticleSystemRenderer>(); if (Object.op_Implicit((Object)(object)component)) { ((Renderer)component).enabled = false; text = text + "\n <root> dome renderer DISABLED (was " + ((Object.op_Implicit((Object)(object)((Renderer)component).sharedMaterial) && Object.op_Implicit((Object)(object)((Renderer)component).sharedMaterial.shader)) ? ((Object)((Renderer)component).sharedMaterial.shader).name : "no shader") + ")"; } else { text += "\n <root> NO ParticleSystemRenderer - the dome was not where the 0.9.20 map put it, so it is still rendering."; } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)(object)root) { continue; } if (Matches(((Object)val).name, AuraDrop)) { ((Component)val).gameObject.SetActive(false); text = text + "\n " + ((Object)val).name + " DROPPED (flare; the burst already plays it)"; continue; } if (((Object)val).name == "Ember") { ParticleSystem component2 = ((Component)val).GetComponent<ParticleSystem>(); if (Object.op_Implicit((Object)(object)component2)) { MainModule main = component2.main; if (LOOP_AURA) { ((MainModule)(ref main)).loop = true; } float duration = ((MainModule)(ref main)).duration; if (AURA_CYCLE_SECONDS > 0f) { ((MainModule)(ref main)).duration = AURA_CYCLE_SECONDS; } if (AURA_LOCAL_SPACE) { ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; } EmissionModule emission = component2.emission; float rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier; ((EmissionModule)(ref emission)).rateOverTimeMultiplier = rateOverTimeMultiplier * AURA_RATE_SCALE; string[] obj = new string[25] { text, "\n ", ((Object)val).name, " KEPT, loop=", ((MainModule)(ref main)).loop.ToString(), ", space=", ((object)((MainModule)(ref main)).simulationSpace/*cast due to .constrained prefix*/).ToString(), ", rate ", rateOverTimeMultiplier.ToString("F1"), " -> ", ((EmissionModule)(ref emission)).rateOverTimeMultiplier.ToString("F1"), " (x", null, null, null, null, null, null, null, null, null, null, null, null, null }; float aURA_RATE_SCALE = AURA_RATE_SCALE; obj[12] = aURA_RATE_SCALE.ToString("0.##"); obj[13] = "), lifetime="; MinMaxCurve startLifetime = ((MainModule)(ref main)).startLifetime; obj[14] = ((MinMaxCurve)(ref startLifetime)).constant.ToString("F2"); obj[15] = " -> about "; float rateOverTimeMultiplier2 = ((EmissionModule)(ref emission)).rateOverTimeMultiplier; startLifetime = ((MainModule)(ref main)).startLifetime; obj[16] = (rateOverTimeMultiplier2 * ((MinMaxCurve)(ref startLifetime)).constant).ToString("F0"); obj[17] = " in the air, max="; obj[18] = ((MainModule)(ref main)).maxParticles.ToString(); obj[19] = ", cycle "; obj[20] = duration.ToString("F2"); obj[21] = " -> "; obj[22] = ((MainModule)(ref main)).duration.ToString("F2"); obj[23] = "s between swells, bursts="; obj[24] = ((EmissionModule)(ref emission)).burstCount.ToString(); text = string.Concat(obj); text += ScaleBursts(emission); startColor = ((MainModule)(ref main)).startColor; haveColour = true; continue; } } text = text + "\n " + ((Object)val).name + " kept as is" + (((Component)val).gameObject.activeSelf ? "" : " [INACTIVE]"); } if (RUNES_ENABLED) { text += AttachRunes(root, haveColour, startColor); } RunicBarrierPlugin.Log.LogMessage((object)text); } private static string AttachRunes(Transform root, bool haveColour, MinMaxGradient emberColour) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_00e2: 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_010a: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: 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_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: 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_0268: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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) if (Object.op_Implicit((Object)(object)root.Find("RunicBarrierRunes"))) { return "\n RunicBarrierRunes already present, not attached twice"; } GameObject val; try { val = SL_PlayVFX.GetVfxSystem((VFXPrefabs)52); } catch (Exception) { val = null; } if ((Object)(object)val == (Object)null) { return "\n runes NOT attached: " + ((object)(VFXPrefabs)52/*cast due to .constrained prefix*/).ToString() + " is not in SideLoader's cache"; } Transform val2 = val.transform.Find("Cloud/Runes"); if (!Object.op_Implicit((Object)(object)val2)) { return "\n runes NOT attached: no 'Cloud/Runes' under " + ((object)(VFXPrefabs)52/*cast due to .constrained prefix*/).ToString(); } if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponent<ParticleSystem>())) { return "\n runes NOT attached: 'Cloud/Runes' has no ParticleSystem"; } GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject); ((Object)obj).name = "RunicBarrierRunes"; obj.transform.SetParent(root, false); obj.transform.localPosition = new Vector3(0f, RUNE_HEIGHT, 0f); obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = Vector3.one; obj.SetActive(true); ParticleSystem component = obj.GetComponent<ParticleSystem>(); MainModule main = component.main; EmissionModule emission = component.emission; string text; if (haveColour) { ((MainModule)(ref main)).startColor = emberColour; text = "startColor -> the aura's " + Describe(emberColour); } else { text = "startColor LEFT GREEN - Ember's colour was not captured"; } ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(RUNE_LIFETIME); if (RUNE_LOCAL_SPACE) { ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; } MinMaxCurve val3; if (Math.Abs(RUNE_SIZE_SCALE - 1f) > 0.001f) { val3 = ((MainModule)(ref main)).startSize; ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(((MinMaxCurve)(ref val3)).constant * RUNE_SIZE_SCALE); } ((EmissionModule)(ref emission)).rateOverTime = new MinMaxCurve(RUNE_RATE); ((EmissionModule)(ref emission)).burstCount = 0; ForceOverLifetimeModule forceOverLifetime = component.forceOverLifetime; ((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled = false; string[] obj2 = new string[21] { "\n RunicBarrierRunes ATTACHED from ", ((object)(VFXPrefabs)52/*cast due to .constrained prefix*/).ToString(), "/Cloud/Runes\n ", text, "\n loop=", ((MainModule)(ref main)).loop.ToString(), ", space=", ((object)((MainModule)(ref main)).simulationSpace/*cast due to .constrained prefix*/).ToString(), ", rate=", ((EmissionModule)(ref emission)).rateOverTimeMultiplier.ToString("F1"), ", lifetime=", null, null, null, null, null, null, null, null, null, null }; val3 = ((MainModule)(ref main)).startLifetime; obj2[11] = ((MinMaxCurve)(ref val3)).constant.ToString("F2"); obj2[12] = " -> about "; obj2[13] = (RUNE_RATE * RUNE_LIFETIME).ToString("F0"); obj2[14] = " in the air, startSize="; val3 = ((MainModule)(ref main)).startSize; obj2[15] = ((MinMaxCurve)(ref val3)).constant.ToString("F2"); obj2[16] = ", bursts="; obj2[17] = ((EmissionModule)(ref emission)).burstCount.ToString(); obj2[18] = ", height="; float rUNE_HEIGHT = RUNE_HEIGHT; obj2[19] = rUNE_HEIGHT.ToString("F2"); obj2[20] = VerticalExtent(component); return string.Concat(obj2); } private static string VerticalExtent(ParticleSystem ps) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0114: 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_014f: Unknown result type (might be due to invalid IL or missing references) ShapeModule shape = ps.shape; VelocityOverLifetimeModule velocityOverLifetime = ps.velocityOverLifetime; ForceOverLifetimeModule forceOverLifetime = ps.forceOverLifetime; object obj; if (!((ShapeModule)(ref shape)).enabled) { obj = "disabled"; } else { string[] obj2 = new string[9] { ((object)((ShapeModule)(ref shape)).shapeType/*cast due to .constrained prefix*/).ToString(), " scale=", null, null, null, null, null, null, null }; Vector3 val = ((ShapeModule)(ref shape)).scale; obj2[2] = ((Vector3)(ref val)).ToString("F2"); obj2[3] = " pos="; val = ((ShapeModule)(ref shape)).position; obj2[4] = ((Vector3)(ref val)).ToString("F2"); obj2[5] = " radius="; obj2[6] = ((ShapeModule)(ref shape)).radius.ToString("F2"); obj2[7] = " thickness="; obj2[8] = ((ShapeModule)(ref shape)).radiusThickness.ToString("F2"); obj = string.Concat(obj2); } string text = "\n shape: " + (string?)obj; return text + "\n drift: velocityOverLifetime=" + (((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled ? ("ON y " + Curve(((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y) + " space=" + ((object)((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space/*cast due to .constrained prefix*/).ToString()) : "off") + ", forceOverLifetime=" + (((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled ? ("ON y " + Curve(((ForceOverLifetimeModule)(ref forceOverLifetime)).y)) : "off"); } private static string Curve(MinMaxCurve c) { //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_001e: Expected I4, but got Unknown //IL_00ef: 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) ParticleSystemCurveMode mode = ((MinMaxCurve)(ref c)).mode; return (int)mode switch { 0 => ((MinMaxCurve)(ref c)).constant.ToString("F2") + " (Constant)", 3 => ((MinMaxCurve)(ref c)).constantMin.ToString("F2") + ".." + ((MinMaxCurve)(ref c)).constantMax.ToString("F2") + " (TwoConstants)", 1 => "CURVE x" + ((MinMaxCurve)(ref c)).curveMultiplier.ToString("F2") + ((((MinMaxCurve)(ref c)).curve != null) ? (" (" + ((MinMaxCurve)(ref c)).curve.keys.Length + " keys)") : ""), 2 => "TWO CURVES x" + ((MinMaxCurve)(ref c)).curveMultiplier.ToString("F2"), _ => ((object)((MinMaxCurve)(ref c)).mode/*cast due to .constrained prefix*/).ToString(), }; } private static string Describe(MinMaxGradient g) { //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_001a: Expected I4, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) ParticleSystemGradientMode mode = ((MinMaxGradient)(ref g)).mode; return (int)mode switch { 0 => Hex(((MinMaxGradient)(ref g)).color), 2 => "TwoColors " + Hex(((MinMaxGradient)(ref g)).colorMin) + " .. " + Hex(((MinMaxGradient)(ref g)).colorMax), 1 => "Gradient (" + ((((MinMaxGradient)(ref g)).gradient != null) ? (((MinMaxGradient)(ref g)).gradient.colorKeys.Length + " keys") : "null") + ")", _ => ((object)((MinMaxGradient)(ref g)).mode/*cast due to .constrained prefix*/).ToString(), }; } private static string Hex(Color c) { //IL_0011: 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_005d: Unknown result type (might be due to invalid IL or missing references) return "#" + Mathf.RoundToInt(Mathf.Clamp01(c.r) * 255f).ToString("X2") + Mathf.RoundToInt(Mathf.Clamp01(c.g) * 255f).ToString("X2") + Mathf.RoundToInt(Mathf.Clamp01(c.b) * 255f).ToString("X2") + " (" + c.r.ToString("F2") + "," + c.g.ToString("F2") + "," + c.b.ToString("F2") + ")"; } private static string ScaleBursts(EmissionModule em) { //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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) int burstCount = ((EmissionModule)(ref em)).burstCount; if (burstCount <= 0) { return ""; } Burst[] array = (Burst[])(object)new Burst[burstCount]; ((EmissionModule)(ref em)).GetBursts(array); string text = ""; for (int i = 0; i < burstCount; i++) { Burst val = array[i]; MinMaxCurve count = ((Burst)(ref val)).count; float constantMax = ((MinMaxCurve)(ref count)).constantMax; ((MinMaxCurve)(ref count)).constantMin = ((MinMaxCurve)(ref count)).constantMin * AURA_BURST_SCALE; ((MinMaxCurve)(ref count)).constantMax = ((MinMaxCurve)(ref count)).constantMax * AURA_BURST_SCALE; ((Burst)(ref val)).count = count; float probability = ((Burst)(ref val)).probability; ((Burst)(ref val)).probability = AURA_BURST_PROBABILITY; ((EmissionModule)(ref em)).SetBurst(i, val); string[] obj = new string[21] { text, "\n burst ", i.ToString(), ": count ", constantMax.ToString("F1"), " -> ", ((MinMaxCurve)(ref count)).constantMax.ToString("F1"), " (x", null, null, null, null, null, null, null, null, null, null, null, null, null }; float aURA_BURST_SCALE = AURA_BURST_SCALE; obj[8] = aURA_BURST_SCALE.ToString("0.##"); obj[9] = ") mode="; obj[10] = ((object)((MinMaxCurve)(ref count)).mode/*cast due to .constrained prefix*/).ToString(); obj[11] = ", probability "; obj[12] = probability.ToString("F2"); obj[13] = " -> "; obj[14] = ((Burst)(ref val)).probability.ToString("F2"); o