Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EnhancedVanillaWeapons v1.1.0
EnhancedVanillaWeapons.dll
Decompiled a week 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.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("EnhancedVanillaWeapons")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("EnhancedVanillaWeapons")] [assembly: AssemblyTitle("EnhancedVanillaWeapons")] [assembly: AssemblyVersion("1.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EnhancedVanillaWeapons { internal static class JotunBane { internal enum PoisonMode { Vanilla, Add, Skip } private class RuptureMark { internal Character Target; internal ZDOID Attacker; internal float CloudPoison; internal float Time; } private class PendingCloud { internal Vector3 Center; internal HitPlan Plan; internal float Radius; internal int StacksEach; } internal class HitPlan { internal bool Rupture; internal int Stacks; internal int Previous; internal float CloudPoison; internal ZDOID Attacker; } private class PendingBurst { internal Vector3 At; internal int Stacks; internal ZDOID Attacker; } private const string AxeName = "$item_axe_jotunbane"; internal const int FullStacks = 3; internal const int MaxStacks = 15; private const string RuptureRpc = "EnhancedVanillaWeapons_JotunRupture"; private const string BurstRpc = "EnhancedVanillaWeapons_JotunBurst"; private const string MilestoneRpc = "EnhancedVanillaWeapons_JotunMilestone"; private const string StacksKey = "EnhancedVanillaWeapons_JotunStacks"; private const string StacksUntilKey = "EnhancedVanillaWeapons_JotunStacksUntil"; private const float RuptureMarkSeconds = 1f; internal const float StackSeconds = 8f; private static readonly FieldRef<SE_Poison, float> DamageLeft = AccessTools.FieldRefAccess<SE_Poison, float>("m_damageLeft"); private static readonly FieldRef<SE_Poison, float> DamagePerHit = AccessTools.FieldRefAccess<SE_Poison, float>("m_damagePerHit"); internal static PoisonMode s_poisonMode; private static float s_addPools; private static bool s_ruptureSwing; private static float s_swingPoison; private static readonly List<RuptureMark> s_marks = new List<RuptureMark>(); private static readonly HashSet<Character> s_popped = new HashSet<Character>(); private static readonly List<PendingCloud> s_pendingClouds = new List<PendingCloud>(); private static bool s_inCloud; internal static int Ruptures; internal static int FullRuptures; internal static int BiggestRupture; private static readonly List<PendingBurst> s_pendingBursts = new List<PendingBurst>(); internal static bool IsBane(ItemData weapon) { return weapon?.m_shared.m_name == "$item_axe_jotunbane"; } internal static void BeforeAttackTrigger(Attack attack, Humanoid character) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) s_ruptureSwing = false; if (Plugin.BaneEnabled.Value && !((Object)(object)character == (Object)null) && !((Object)(object)character != (Object)(object)Player.m_localPlayer)) { ItemData weapon = attack.GetWeapon(); if (IsBane(weapon) && !(attack.m_attackAnimation != weapon.m_shared.m_secondaryAttack.m_attackAnimation)) { s_ruptureSwing = true; s_swingPoison = weapon.GetDamage().m_poison; } } } internal static void AfterAttackTrigger() { s_ruptureSwing = false; } internal static void OnDamage(Character victim, HitData hit) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (s_ruptureSwing && !s_inCloud && !((Object)(object)victim == (Object)null) && !victim.IsPlayer() && !((Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer)) { ZNetView component = ((Component)victim).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { component.InvokeRPC("EnhancedVanillaWeapons_JotunRupture", new object[2] { hit.m_attacker, s_swingPoison }); } } } internal static void Register(Character character, ZNetView nview) { if (!(character is Player) && !((Object)(object)nview == (Object)null) && nview.IsValid()) { nview.Register<ZDOID, float>("EnhancedVanillaWeapons_JotunRupture", (Action<long, ZDOID, float>)delegate(long sender, ZDOID attacker, float cloudPoison) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) OnRuptureMark(character, nview, attacker, cloudPoison); }); nview.Register<Vector3, int, ZDOID>("EnhancedVanillaWeapons_JotunBurst", (Action<long, Vector3, int, ZDOID>)delegate(long sender, Vector3 at, int stacks, ZDOID attacker) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) OnBurst(at, stacks, attacker); }); nview.Register<int>("EnhancedVanillaWeapons_JotunMilestone", (Action<long, int>)delegate(long sender, int stacks) { StackCues.OnMilestone(character, stacks); }); } } internal static int GetStacks(Character character) { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || (Object)(object)ZNet.instance == (Object)null) { return 0; } ZDO zDO = component.GetZDO(); int num = zDO.GetInt("EnhancedVanillaWeapons_JotunStacks", 0); if (num <= 0 || NowMs() >= zDO.GetLong("EnhancedVanillaWeapons_JotunStacksUntil", 0L)) { return 0; } return num; } private static void OnRuptureMark(Character character, ZNetView nview, ZDOID attacker, float cloudPoison) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)character == (Object)null) && nview.IsOwner()) { TakeMark(character, attacker); s_marks.Add(new RuptureMark { Target = character, Attacker = attacker, CloudPoison = cloudPoison, Time = Time.time }); } } private static RuptureMark TakeMark(Character target, ZDOID attacker) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < s_marks.Count; i++) { RuptureMark ruptureMark = s_marks[i]; if (!((Object)(object)ruptureMark.Target != (Object)(object)target) && !(ruptureMark.Attacker != attacker)) { s_marks.RemoveAt(i); return ruptureMark; } } return null; } internal static HitPlan PlanHit(Character target, ZNetView nview, HitData hit) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) s_poisonMode = PoisonMode.Vanilla; if (!Plugin.BaneEnabled.Value || (Object)(object)nview == (Object)null || !nview.IsOwner() || target.IsPlayer() || target.IsDead() || target.GetHealth() <= 0f) { return null; } if ((int)hit.m_skill == 7 && !(hit.m_damage.m_poison <= 0f)) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && HoldsBane(val)) { int stacks = GetStacks(target); HitPlan hitPlan = new HitPlan { Attacker = hit.m_attacker, Previous = stacks }; RuptureMark ruptureMark = TakeMark(target, hit.m_attacker); if (ruptureMark != null && Time.time - ruptureMark.Time < 1f && stacks > 0) { hitPlan.Rupture = true; hitPlan.Stacks = stacks; hitPlan.CloudPoison = ruptureMark.CloudPoison; s_poisonMode = PoisonMode.Skip; return hitPlan; } hitPlan.Stacks = Mathf.Min(stacks + 1, 15); s_poisonMode = PoisonMode.Add; int num = Mathf.Max(0, hitPlan.Stacks - 3); s_addPools = (float)Mathf.Min(hitPlan.Stacks, 3) * (1f + (float)(num * Plugin.BaneExtraDotPercent.Value) / 100f); return hitPlan; } } return null; } private static bool HoldsBane(Player attacker) { ZNetView component = ((Component)attacker).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || (Object)(object)ObjectDB.instance == (Object)null) { return false; } ZDO zDO = component.GetZDO(); if (!IsBanePrefab(zDO.GetInt(ZDOVars.s_rightItem, 0))) { return IsBanePrefab(zDO.GetInt(ZDOVars.s_leftItem, 0)); } return true; } private static bool IsBanePrefab(int hash) { if (hash == 0) { return false; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val != (Object)null) { return IsBane(val.m_itemData); } return false; } internal static void FinishHit(Character target, ZNetView nview, HitPlan plan) { s_poisonMode = PoisonMode.Vanilla; if (plan == null || (Object)(object)target == (Object)null || !nview.IsValid()) { return; } if (plan.Rupture) { Rupture(target, nview, plan); return; } SetStacks(nview, plan.Stacks, StacksUntil()); if (target.GetHealth() > 0f) { for (int i = 3; i <= 15; i += 3) { if (plan.Stacks >= i && plan.Previous < i) { nview.InvokeRPC(ZNetView.Everybody, "EnhancedVanillaWeapons_JotunMilestone", new object[1] { i }); } } } if (Plugin.LogBane.Value) { Plugin.Log.LogInfo((object)$"Jotun Bane: {target.m_name} at {plan.Stacks} stack(s)"); } } internal static bool AddPoison(Character target, SEMan seman, float damage, short variant) { PoisonMode poisonMode = s_poisonMode; s_poisonMode = PoisonMode.Vanilla; switch (poisonMode) { case PoisonMode.Skip: return false; case PoisonMode.Add: if (!(damage <= 0f)) { StatusEffect statusEffect = seman.GetStatusEffect(SEMan.s_statusEffectPoison); SE_Poison val = (SE_Poison)(object)((statusEffect is SE_Poison) ? statusEffect : null); if ((Object)(object)val == (Object)null) { StatusEffect obj = seman.AddStatusEffect(SEMan.s_statusEffectPoison, false, 0, 0f, variant); val = (SE_Poison)(object)((obj is SE_Poison) ? obj : null); } if ((Object)(object)val == (Object)null) { return true; } float num = DamageLeft.Invoke(val); float num2 = s_addPools * damage; if (num2 < num && ((StatusEffect)val).m_ttl != 8f) { return false; } SetPoison(val, num2); return false; } goto default; default: return true; } } private static void SetPoison(SE_Poison poison, float total) { DamageLeft.Invoke(poison) = total; ((StatusEffect)poison).m_ttl = 8f; int num = Mathf.Max(1, (int)(8f / poison.m_damageInterval)); DamagePerHit.Invoke(poison) = total / (float)num; ((StatusEffect)poison).ResetTime(); } private static long StacksUntil() { return NowMs() + 8000; } private static void Rupture(Character target, ZNetView nview, HitPlan plan) { //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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) Vector3 centerPoint = target.GetCenterPoint(); SetStacks(nview, 0, 0L); s_popped.Add(target); bool flag = plan.Stacks >= 3; StatusEffect statusEffect = target.GetSEMan().GetStatusEffect(SEMan.s_statusEffectPoison); SE_Poison val = (SE_Poison)(object)((statusEffect is SE_Poison) ? statusEffect : null); float num = (((Object)(object)val != (Object)null) ? DamageLeft.Invoke(val) : 0f) * Plugin.BanePoisonMultiplier.Value; if ((Object)(object)val != (Object)null) { target.GetSEMan().RemoveStatusEffect((StatusEffect)(object)val, true); } if (num > 0f) { HitData val2 = new HitData { m_point = centerPoint, m_hitType = (HitType)7, m_attacker = plan.Attacker }; val2.m_damage.m_poison = num; target.ApplyDamage(val2, true, false, (DamageModifier)0); } float num2 = 1f + (float)(Mathf.Max(0, plan.Stacks - 3) * Plugin.BaneRuptureGrowthPercent.Value) / 100f; float num3 = (float)(Plugin.BaneBluntPerStack.Value * plan.Stacks) * num2; float num4 = (float)(Plugin.BaneExtraPoison.Value * plan.Stacks) * num2; if (num3 > 0f || num4 > 0f) { HitData val3 = new HitData { m_point = centerPoint, m_hitType = (HitType)2, m_attacker = plan.Attacker, m_skill = (SkillType)7 }; val3.m_damage.m_blunt = num3; val3.m_damage.m_poison = num4; DamageModifier val4 = default(DamageModifier); val3.ApplyResistance(target.GetDamageModifiers((WeakSpot)null), ref val4); target.ApplyDamage(val3, true, true, val4); } nview.InvokeRPC(ZNetView.Everybody, "EnhancedVanillaWeapons_JotunBurst", new object[3] { centerPoint, plan.Stacks, plan.Attacker }); float num5 = CloudRadius(plan.Stacks); if (Plugin.LogBane.Value) { Plugin.Log.LogInfo((object)($"Jotun Bane: ruptured {target.m_name} at {plan.Stacks} stack(s): {num:0} poison, {num4:0} extra poison, {num3:0} blunt before resistance" + (flag ? $", rot cloud {num5:0.#} m" : ""))); } if (flag) { s_pendingClouds.Add(new PendingCloud { Center = centerPoint, Plan = plan, Radius = num5, StacksEach = CloudStacks(plan.Stacks) }); } } internal static int CloudStacks(int stacks) { return Mathf.Max(1, stacks / 3); } internal static float CloudRadius(int stacks) { return Plugin.BaneCloudRadius.Value + (float)Mathf.Max(0, stacks - 3) * Plugin.BaneCloudRadiusPerExtra.Value; } private static void RotCloud(Vector3 center, HitPlan plan, float radius, int stacksEach) { //IL_001b: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_010c: 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_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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown if (plan.CloudPoison <= 0f) { return; } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.FindInstance(plan.Attacker) : null); Character val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null); if ((Object)(object)val2 == (Object)null) { return; } List<Character> list = new List<Character>(); foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !s_popped.Contains(allCharacter) && !allCharacter.IsDead() && !allCharacter.IsPlayer() && BaseAI.IsEnemy(val2, allCharacter) && !(Vector3.Distance(center, allCharacter.GetCenterPoint()) > radius + allCharacter.GetRadius())) { list.Add(allCharacter); } } s_inCloud = true; try { foreach (Character item in list) { Vector3 centerPoint = item.GetCenterPoint(); for (int i = 0; i < stacksEach; i++) { HitData val3 = new HitData { m_point = centerPoint }; Vector3 val4 = centerPoint - center; val3.m_dir = ((Vector3)(ref val4)).normalized; val3.m_hitType = (HitType)2; val3.m_skill = (SkillType)7; val3.m_attacker = plan.Attacker; HitData val5 = val3; val5.m_damage.m_poison = plan.CloudPoison; item.Damage(val5); } } } finally { s_inCloud = false; } } private static void SetStacks(ZNetView nview, int stacks, long until) { ZDO zDO = nview.GetZDO(); zDO.Set("EnhancedVanillaWeapons_JotunStacks", stacks); zDO.Set("EnhancedVanillaWeapons_JotunStacksUntil", until); } private static long NowMs() { return (long)(ZNet.instance.GetTimeSeconds() * 1000.0); } internal static void Update() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (s_marks.Count > 0) { s_marks.RemoveAll((RuptureMark mark) => (Object)(object)mark.Target == (Object)null || Time.time - mark.Time > 1f); } if (s_pendingClouds.Count > 0) { List<PendingCloud> list = new List<PendingCloud>(s_pendingClouds); s_pendingClouds.Clear(); foreach (PendingCloud item in list) { RotCloud(item.Center, item.Plan, item.Radius, item.StacksEach); } } s_popped.Clear(); if (s_pendingBursts.Count > 0) { List<PendingBurst> bursts = new List<PendingBurst>(s_pendingBursts); s_pendingBursts.Clear(); SpawnBursts(bursts); } RotCloudVisual.Update(); StackCues.Update(); } private static void OnBurst(Vector3 at, int stacks, ZDOID attacker) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) s_pendingBursts.Add(new PendingBurst { At = at, Stacks = stacks, Attacker = attacker }); } private static void SpawnBursts(List<PendingBurst> bursts) { //IL_0021: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) PendingBurst pendingBurst = bursts[0]; ZDOID val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Character)Player.m_localPlayer).GetZDOID() : ZDOID.None); foreach (PendingBurst burst in bursts) { if (burst.Stacks > pendingBurst.Stacks) { pendingBurst = burst; } if (!(val == ZDOID.None) && !(burst.Attacker != val)) { Ruptures++; if (burst.Stacks >= 3) { FullRuptures++; } BiggestRupture = Mathf.Max(BiggestRupture, burst.Stacks); } } ModSounds.PlayPop(pendingBurst.At, pendingBurst.Stacks); if (Plugin.LogBane.Value) { Plugin.Log.LogInfo((object)$"Jotun Bane: pop sound for {pendingBurst.Stacks} stack(s), {bursts.Count} pop(s) at once"); } foreach (PendingBurst burst2 in bursts) { if (burst2.Stacks >= 3) { RotCloudVisual.Spawn(burst2.At, CloudRadius(burst2.Stacks), Mathf.InverseLerp(3f, 15f, (float)burst2.Stacks)); } } } } internal static class RotCloudVisual { private class Cloud { internal ParticleSystem[] Systems; internal Light[] Lights; internal float[] Intensities; internal Light Flash; internal float Start; internal Transform Holder; internal float Spin; internal float SpinSeconds; } private const string Prefab = "bonemass_aoe"; private const string ParticlesChild = "particles"; private const float BonemassRadius = 9f; private const string GasMaterial = "aoe_smoke"; private const string MistMaterial = "heavymist_mistlands"; private static Material s_mist; private static bool s_mistMissing; private static readonly Color GasColor = new Color(0.25f, 0.5f, 0.1f, 0.6f); private const int BasePuffs = 22; private const int MaxPuffs = 72; private const float BaseGasLifetime = 4f; private const float MaxGasLifetime = 6.5f; private const float MaxGasAlpha = 0.75f; private const float BaseRise = -0.02f; private const float MaxRise = -0.15f; private const float MaxSpinDegrees = 140f; private const float DayDarken = 0.7f; private const float NightAlphaBoost = 0.1f; private const float NightPuffBoost = 1.35f; private const float BlastReach = 0.6f; private const float RingReach = 0.9f; private const float RingPuffShare = 0.4f; private const float EmitSeconds = 1f; private const float Lifetime = 10f; private static readonly Color FlashColor = new Color(0.6f, 0.9f, 0.25f, 1f); private const float FlashIntensity = 2.5f; private const float FlashSeconds = 0.6f; private static readonly List<Cloud> s_clouds = new List<Cloud>(); internal static void Spawn(Vector3 position, float radius, float over) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: 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_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) ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab("bonemass_aoe"); obj = ((prefab != null) ? prefab.transform.Find("particles") : null); } Transform val = (Transform)obj; if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"bonemass_aoe/particles not found (game update?); the rot cloud won't show."); return; } GameObject val2 = new GameObject("EnhancedVanillaWeapons_RotCloud"); val2.SetActive(false); val2.transform.position = position; Object.Instantiate<GameObject>(((Component)val).gameObject, val2.transform, false); if ((Object)(object)val2.GetComponentInChildren<Aoe>(true) != (Object)null || (Object)(object)val2.GetComponentInChildren<ZNetView>(true) != (Object)null) { Plugin.Log.LogWarning((object)"bonemass_aoe/particles has gameplay parts now; the rot cloud won't show."); Object.Destroy((Object)(object)val2); return; } float num = radius / 9f; bool daylight = EnvMan.IsDaylight(); ParticleSystem val3 = null; ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val4 in componentsInChildren) { MainModule main = val4.main; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; ParticleSystemRenderer component = ((Component)val4).GetComponent<ParticleSystemRenderer>(); if ((((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).sharedMaterial != (Object)null) ? ((Object)((Renderer)component).sharedMaterial).name : "").Contains("aoe_smoke")) { ShapeBlast(val4, radius, num, over, daylight); val3 = val4; continue; } EmissionModule emission = val4.emission; ((EmissionModule)(ref emission)).enabled = false; SubEmittersModule subEmitters = val4.subEmitters; ((SubEmittersModule)(ref subEmitters)).enabled = false; if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } } if ((Object)(object)val3 != (Object)null) { ShapeRing(Object.Instantiate<GameObject>(((Component)val3).gameObject, ((Component)val3).transform.parent).GetComponent<ParticleSystem>(), radius, num, over, daylight); } ParticleSystem[] componentsInChildren2 = val2.GetComponentsInChildren<ParticleSystem>(true); val2.transform.localScale = Vector3.one * num; Light val5 = val2.AddComponent<Light>(); val5.type = (LightType)2; val5.color = FlashColor; val5.range = radius * 1.5f; val5.intensity = 2.5f; val5.shadows = (LightShadows)0; Light[] componentsInChildren3 = val2.GetComponentsInChildren<Light>(true); Cloud cloud = new Cloud { Systems = componentsInChildren2, Lights = componentsInChildren3, Intensities = new float[componentsInChildren3.Length], Flash = val5, Start = Time.time, Holder = val2.transform, Spin = 140f * over, SpinSeconds = Mathf.Lerp(4f, 6.5f, over) }; for (int j = 0; j < componentsInChildren3.Length; j++) { cloud.Intensities[j] = componentsInChildren3[j].intensity; } val2.SetActive(true); Object.Destroy((Object)(object)val2, 10f); s_clouds.Add(cloud); } private static void ShapeBlast(ParticleSystem system, float radius, float scale, float over, bool daylight) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Lerp(4f, 6.5f, over); MainModule main = system.main; ((MainModule)(ref main)).startDelay = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(num * 0.8f, num); float num2 = (daylight ? 0.7f : 1f); float num3 = Mathf.Lerp(GasColor.a, 0.75f, over) + (daylight ? 0f : 0.1f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(GasColor.r * num2, GasColor.g * num2, GasColor.b * num2, Mathf.Clamp01(num3))); ((MainModule)(ref main)).startSize = new MinMaxCurve(radius * 0.35f / scale, radius * 0.55f / scale); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(Mathf.Lerp(-0.02f, -0.15f, over)); EmissionModule emission = system.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); int num4 = Mathf.RoundToInt(Mathf.Lerp(22f, 72f, over) * (daylight ? 1f : 1.35f)); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)num4) }); ((MainModule)(ref main)).maxParticles = Mathf.Max(((MainModule)(ref main)).maxParticles, num4); SubEmittersModule subEmitters = system.subEmitters; ((SubEmittersModule)(ref subEmitters)).enabled = false; ShapeModule shape = system.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)2; ((ShapeModule)(ref shape)).radius = 0.5f / scale; ((ShapeModule)(ref shape)).rotation = new Vector3(-90f, 0f, 0f); AnimationCurve val = new AnimationCurve((Keyframe[])(object)new Keyframe[4] { new Keyframe(0f, 1f), new Keyframe(0.15f, 0.35f), new Keyframe(0.5f, 0.08f), new Keyframe(1f, 0f) }); float num5 = 0.6f * radius / (num * 0.9f * 0.25f) / scale; ((MainModule)(ref main)).startSpeed = new MinMaxCurve(num5 * 0.8f, num5 * 1.1f); VelocityOverLifetimeModule velocityOverLifetime = system.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).speedModifier = new MinMaxCurve(1f, val); SizeOverLifetimeModule sizeOverLifetime = system.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 0.5f, 1f, 1.6f)); Material mist = GetMist(); ParticleSystemRenderer component = ((Component)system).GetComponent<ParticleSystemRenderer>(); if ((Object)(object)mist != (Object)null && (Object)(object)component != (Object)null) { ((Renderer)component).sharedMaterial = mist; } } private static void ShapeRing(ParticleSystem system, float radius, float scale, float over, bool daylight) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Lerp(4f, 6.5f, over); MainModule main = system.main; ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.02f); float num2 = 0.9f * radius / (num * 0.9f * 0.25f) / scale; ((MainModule)(ref main)).startSpeed = new MinMaxCurve(num2 * 0.8f, num2 * 1.1f); int num3 = Mathf.RoundToInt(Mathf.Lerp(22f, 72f, over) * 0.4f * (daylight ? 1f : 1.35f)); ((MainModule)(ref main)).maxParticles = Mathf.Max(((MainModule)(ref main)).maxParticles, num3); EmissionModule emission = system.emission; ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)num3) }); ShapeModule shape = system.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)10; ((ShapeModule)(ref shape)).radius = 0.5f / scale; ((ShapeModule)(ref shape)).arc = 360f; ((ShapeModule)(ref shape)).rotation = new Vector3(-90f, 0f, 0f); ((ShapeModule)(ref shape)).randomDirectionAmount = 0.1f; } private static Material GetMist() { if ((Object)(object)s_mist != (Object)null || s_mistMissing) { return s_mist; } Material[] array = Resources.FindObjectsOfTypeAll<Material>(); foreach (Material val in array) { if (((Object)val).name == "heavymist_mistlands") { s_mist = val; break; } } s_mistMissing = (Object)(object)s_mist == (Object)null; if (s_mistMissing) { Plugin.Log.LogWarning((object)"Material heavymist_mistlands not found (game update?); the rot cloud keeps Bonemass's texture."); } return s_mist; } internal static void Update() { for (int num = s_clouds.Count - 1; num >= 0; num--) { Cloud cloud = s_clouds[num]; float num2 = Time.time - cloud.Start; if ((Object)(object)cloud.Flash == (Object)null) { s_clouds.RemoveAt(num); } else { float num3 = Mathf.Clamp01(1f - num2 / 0.6f); if (cloud.Systems != null && num2 >= 1f) { ParticleSystem[] systems = cloud.Systems; foreach (ParticleSystem val in systems) { if ((Object)(object)val != (Object)null) { val.Stop(false, (ParticleSystemStopBehavior)1); } } cloud.Systems = null; LightFlicker[] componentsInChildren = ((Component)cloud.Flash).GetComponentsInChildren<LightFlicker>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } } float num4 = Mathf.Clamp01(1f - (num2 - 1f) / 0.6f); for (int j = 0; j < cloud.Lights.Length; j++) { Light val2 = cloud.Lights[j]; if (!((Object)(object)val2 == (Object)null)) { val2.intensity = (((Object)(object)val2 == (Object)(object)cloud.Flash) ? (2.5f * num3 * num3) : ((num2 < 1f) ? val2.intensity : (cloud.Intensities[j] * num4))); } } float num5 = Mathf.Clamp01(1f - num2 / cloud.SpinSeconds); if (cloud.Spin > 0f && num5 > 0f && (Object)(object)cloud.Holder != (Object)null) { cloud.Holder.Rotate(0f, cloud.Spin * num5 * num5 * Time.deltaTime, 0f, (Space)0); } if (cloud.Systems == null && num4 <= 0f && num3 <= 0f && (cloud.Spin <= 0f || num5 <= 0f)) { s_clouds.RemoveAt(num); } } } } } internal static class StackTiers { private static readonly Color[] Colors = (Color[])(object)new Color[5] { new Color(0.45f, 0.9f, 0.2f, 1f), new Color(1f, 0.85f, 0.15f, 1f), new Color(1f, 0.5f, 0.05f, 1f), new Color(1f, 0.1f, 0.08f, 1f), new Color(0.6f, 0.15f, 0.85f, 1f) }; internal static int Tier(int stacks) { return Mathf.Clamp((stacks - 1) / 3, 0, Colors.Length - 1); } internal static Color Color(int tier) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) return Colors[Mathf.Clamp(tier, 0, Colors.Length - 1)]; } } internal static class StackCues { private class Glow { internal Light Light; internal int Tier; } private const float ReadyGap = 0.25f; private static bool s_readyPending; private static int s_readyStacks; private static Vector3 s_readyAt; private static float s_nextReady; private const float GlowIntensity = 0.8f; private const float GlowPerTier = 0.25f; private const float GlowPulse = 0.6f; private const float GlowPulseSpeed = 4f; private const float ScanInterval = 0.2f; private const float ScanRange = 40f; private const float FlashSeconds = 0.4f; private static readonly Dictionary<Character, Glow> s_glows = new Dictionary<Character, Glow>(); private static readonly Dictionary<Character, float> s_flashes = new Dictionary<Character, float>(); private static readonly List<Character> s_drop = new List<Character>(); private static float s_nextScan; internal static void OnMilestone(Character character, int stacks) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)character == (Object)null)) { s_flashes[character] = Time.time; if (!s_readyPending || stacks > s_readyStacks) { s_readyPending = true; s_readyStacks = stacks; s_readyAt = character.GetCenterPoint(); } } } internal static float Flash(Character character) { if (!s_flashes.TryGetValue(character, out var value)) { return 0f; } float num = (Time.time - value) / 0.4f; if (num < 1f) { return (1f - num) * (1f - num); } s_flashes.Remove(character); return 0f; } internal static void Update() { //IL_0029: 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) if (s_readyPending) { s_readyPending = false; if (Time.time >= s_nextReady) { s_nextReady = Time.time + 0.25f; ModSounds.PlayReady(s_readyAt, s_readyStacks); } } if (Time.time >= s_nextScan) { s_nextScan = Time.time + 0.2f; Scan(); } if (s_glows.Count == 0) { return; } float num = 0.5f + 0.5f * Mathf.Sin(Time.time * 4f); foreach (Glow value in s_glows.Values) { if (!((Object)(object)value.Light == (Object)null)) { value.Light.color = StackTiers.Color(value.Tier); value.Light.intensity = 0.8f + 0.25f * (float)value.Tier + 0.6f * num; } } } private static void Scan() { //IL_0064: 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) Player localPlayer = Player.m_localPlayer; bool flag = Plugin.BaneEnabled.Value && (Object)(object)localPlayer != (Object)null; if (flag) { foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer() && !s_glows.ContainsKey(allCharacter) && !allCharacter.IsDead() && !(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)allCharacter).transform.position) > 40f) && JotunBane.GetStacks(allCharacter) >= 3) { s_glows[allCharacter] = new Glow { Light = AddGlow(allCharacter) }; } } } s_drop.Clear(); foreach (KeyValuePair<Character, Glow> s_glow in s_glows) { Character key = s_glow.Key; int num = ((flag && (Object)(object)key != (Object)null && !key.IsDead()) ? JotunBane.GetStacks(key) : 0); if (num >= 3) { s_glow.Value.Tier = StackTiers.Tier(num); continue; } if ((Object)(object)s_glow.Value.Light != (Object)null) { Object.Destroy((Object)(object)((Component)s_glow.Value.Light).gameObject); } s_drop.Add(key); } foreach (Character item in s_drop) { s_glows.Remove(item); } s_drop.Clear(); foreach (KeyValuePair<Character, float> s_flash in s_flashes) { if ((Object)(object)s_flash.Key == (Object)null || Time.time - s_flash.Value >= 0.4f) { s_drop.Add(s_flash.Key); } } foreach (Character item2 in s_drop) { s_flashes.Remove(item2); } } private static Light AddGlow(Character character) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) GameObject val = new GameObject("EnhancedVanillaWeapons_FullGlow"); val.transform.SetParent(((Component)character).transform, false); val.transform.position = character.GetCenterPoint(); Light obj = val.AddComponent<Light>(); obj.type = (LightType)2; obj.color = StackTiers.Color(0); obj.range = Mathf.Clamp(character.GetRadius() * 4f, 3f, 8f); obj.intensity = 0.8f; obj.shadows = (LightShadows)0; return obj; } } internal static class StackPips { private const string RowName = "EnhancedVanillaWeapons_JotunPips"; private const string CountName = "Count"; private const int Slots = 3; private const float PulseSpeed = 9f; private const float PulseGrowth = 0.35f; private const float HaloScale = 2.2f; private const float HaloAlpha = 0.25f; private const float HaloAlphaPulse = 0.35f; private const float GlowyTier = 3f; private const float GlowyHaloBonus = 0.25f; private const float PeakWhiten = 0.4f; private const float FlashGrowth = 1f; private const float Gap = 3f; private const float CountFontScale = 0.8f; private static readonly FieldInfo HudsField = AccessTools.Field(typeof(EnemyHud), "m_huds"); private static readonly FieldInfo GuiField = AccessTools.Field(AccessTools.Inner(typeof(EnemyHud), "HudData"), "m_gui"); internal static void Update(EnemyHud hud) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_021d: 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_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0261: 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_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) if (GuiField == null || !(HudsField?.GetValue(hud) is IDictionary dictionary)) { return; } bool value = Plugin.BaneEnabled.Value; float num = 0.5f + 0.5f * Mathf.Sin(Time.time * 9f); foreach (DictionaryEntry item in dictionary) { object key = item.Key; Character val = (Character)((key is Character) ? key : null); object? value2 = GuiField.GetValue(item.Value); GameObject val2 = (GameObject)((value2 is GameObject) ? value2 : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !val2.activeSelf || val.IsPlayer()) { continue; } Transform val3 = val2.transform.Find("Health"); if ((Object)(object)val3 == (Object)null) { continue; } int num2 = (value ? JotunBane.GetStacks(val) : 0); Transform val4 = val3.Find("EnhancedVanillaWeapons_JotunPips"); if ((Object)(object)val4 == (Object)null) { if (num2 == 0) { continue; } val4 = BuildRow((RectTransform)val3, val2.transform); } bool flag = num2 >= 3; int num3 = StackTiers.Tier(num2); int num4 = ((num2 > 0) ? ((num2 - 1) % 3 + 1) : 0); float num5 = (flag ? StackCues.Flash(val) : 0f); float num6 = (flag ? (Mathf.Max(num, num5) * 0.4f) : 0f); float num7 = (flag ? (1f + 0.35f * num + 1f * num5) : 1f); float num8 = Mathf.Clamp01(0.25f + 0.35f * Mathf.Max(num, num5) + (((float)num3 >= 3f) ? 0.25f : 0f)); for (int i = 0; i < 3; i++) { Transform child = val4.GetChild(i); bool flag2 = i < num4 || num3 > 0; ((Component)child).gameObject.SetActive(flag2); if (flag2) { Color val5 = StackTiers.Color((i < num4) ? num3 : (num3 - 1)); Color color = Color.Lerp(val5, Color.white, num6); child.localScale = Vector3.one * num7; Transform child2 = child.GetChild(0); ((Component)child2).gameObject.SetActive(flag); if (flag) { ((Graphic)((Component)child2).GetComponent<Image>()).color = new Color(val5.r, val5.g, val5.b, num8); } ((Graphic)((Component)child.GetChild(1)).GetComponent<Image>()).color = color; } } Transform obj = val4.Find("Count"); TMP_Text val6 = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null); if ((Object)(object)val6 != (Object)null) { bool flag3 = num2 > 3; ((Component)val6).gameObject.SetActive(flag3); if (flag3) { val6.text = "x" + num2; ((Graphic)val6).color = Color.Lerp(StackTiers.Color(num3), Color.white, 0.25f); } } } } private static Transform BuildRow(RectTransform health, Transform gui) { //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00fc: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_0196: Expected O, but got Unknown Rect rect = health.rect; float num = Mathf.Clamp(((Rect)(ref rect)).height, 6f, 14f); RectTransform val = (RectTransform)new GameObject("EnhancedVanillaWeapons_JotunPips", new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent((Transform)(object)health, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 0.5f); val.anchorMax = val2; val.anchorMin = val2; val.pivot = new Vector2(0f, 0.5f); val.anchoredPosition = new Vector2(3f + num * 0.2f, 0f); val.sizeDelta = new Vector2(3f * (num + 3f), num); for (int i = 0; i < 3; i++) { GameObject val3 = new GameObject("Pip" + i, new Type[1] { typeof(RectTransform) }); RectTransform val4 = (RectTransform)val3.transform; ((Transform)val4).SetParent((Transform)(object)val, false); ((Vector2)(ref val2))..ctor(0f, 0.5f); val4.anchorMax = val2; val4.anchorMin = val2; val4.sizeDelta = new Vector2(num * 0.75f, num * 0.75f); val4.anchoredPosition = new Vector2((float)i * (num + 3f) + num * 0.5f, 0f); ((Transform)val4).localRotation = Quaternion.Euler(0f, 0f, 45f); AddDiamond(val4, "Halo", 2.2f).SetActive(false); AddDiamond(val4, "Core", 1f); val3.SetActive(false); } AddCount(val, gui, num); return (Transform)(object)val; } private static void AddCount(RectTransform row, Transform gui, float size) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) Transform val = gui.Find("Name"); TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null); if ((Object)(object)val2 == (Object)null) { return; } GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, (Transform)(object)row, false); ((Object)val3).name = "Count"; foreach (Transform item in val3.transform) { Object.Destroy((Object)(object)((Component)item).gameObject); } RectTransform val4 = (RectTransform)val3.transform; Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(0f, 0.5f); val4.anchorMax = val5; val4.anchorMin = val5; val4.pivot = new Vector2(0f, 0.5f); val4.anchoredPosition = new Vector2(3f * (size + 3f) + 3f, 0f); val4.sizeDelta = new Vector2(size * 4f, size * 2f); ((Transform)val4).localRotation = Quaternion.identity; ((Transform)val4).localScale = Vector3.one; TMP_Text component = val3.GetComponent<TMP_Text>(); component.fontSize = val2.fontSize * 0.8f; component.enableAutoSizing = false; component.alignment = (TextAlignmentOptions)513; component.textWrappingMode = (TextWrappingModes)0; ((Graphic)component).raycastTarget = false; val3.SetActive(false); } private static GameObject AddDiamond(RectTransform pip, string name, float scale) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0053: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)pip, false); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.sizeDelta = Vector2.zero; ((Transform)val2).localScale = Vector3.one * scale; Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = StackTiers.Color(0); ((Graphic)obj).raycastTarget = false; return val; } } [HarmonyPatch(typeof(Character), "Awake")] internal static class CharacterAwakePatch { private static void Postfix(Character __instance, ZNetView ___m_nview) { JotunBane.Register(__instance, ___m_nview); } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] internal static class BaneAttackTriggerPatch { private static void Prefix(Attack __instance, Humanoid ___m_character) { JotunBane.BeforeAttackTrigger(__instance, ___m_character); } private static void Finalizer() { JotunBane.AfterAttackTrigger(); } } [HarmonyPatch(typeof(Character), "Damage")] internal static class BaneDamagePatch { private static void Prefix(Character __instance, HitData hit) { JotunBane.OnDamage(__instance, hit); } } [HarmonyPatch(typeof(Character), "RPC_Damage")] internal static class BaneRpcDamagePatch { private static void Prefix(Character __instance, HitData hit, ZNetView ___m_nview, out JotunBane.HitPlan __state) { __state = JotunBane.PlanHit(__instance, ___m_nview, hit); } private static void Postfix(Character __instance, ZNetView ___m_nview, JotunBane.HitPlan __state) { JotunBane.FinishHit(__instance, ___m_nview, __state); } private static void Finalizer() { JotunBane.s_poisonMode = JotunBane.PoisonMode.Vanilla; } } [HarmonyPatch(typeof(Character), "AddPoisonDamage")] internal static class BaneAddPoisonPatch { private static bool Prefix(Character __instance, SEMan ___m_seman, float damage, short variant) { return JotunBane.AddPoison(__instance, ___m_seman, damage, variant); } } [HarmonyPatch(typeof(EnemyHud), "UpdateHuds")] internal static class EnemyHudPatch { private static void Postfix(EnemyHud __instance) { StackPips.Update(__instance); } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class BaneTooltipPatch { private const string Line = "\n\n<color=orange>Rot</color>: every hit adds a rot stack, making the poison stronger.\n\n<color=orange>Rupture</color> (secondary attack): bursts it all at once, harder per stack, and from 3+ stacks releases a rot cloud explosion."; private static void Postfix(ItemData item, bool appending, ref string __result) { if (!appending && Plugin.BaneEnabled.Value && JotunBane.IsBane(item)) { string description = item.m_shared.m_description; if (__result.StartsWith(description, StringComparison.Ordinal)) { __result = __result.Insert(description.Length, "\n\n<color=orange>Rot</color>: every hit adds a rot stack, making the poison stronger.\n\n<color=orange>Rupture</color> (secondary attack): bursts it all at once, harder per stack, and from 3+ stacks releases a rot cloud explosion."); } } } } internal static class ModSounds { private class Fade { internal AudioSource Source; internal float StartVolume; internal float Progress; internal float Seconds; } private const string MixerSourcePrefab = "sfx_perfect_dodge"; private const float GlideVolume = 0.24f; private static readonly MethodInfo SetData = typeof(AudioClip).GetMethod("SetData", new Type[2] { typeof(float[]), typeof(int) }); private static AudioClip s_glide; private static AudioMixerGroup s_sfxGroup; private static readonly List<Fade> s_fades = new List<Fade>(); private static readonly float[] PopVolumes = new float[3] { 0.6f, 0.85f, 1f }; private static readonly float[] PopPitches = new float[3] { 1.15f, 1f, 0.92f }; private static AudioClip s_pop; private static AudioClip s_popFull; private const float MaxStacksPitch = 0.8f; private const float MaxLayerVolume = 0.75f; private const float MaxBoomVolume = 0.5f; private const float MaxDoubleVolume = 0.8f; private const float HeavyPitchAtMax = 0.94f; private static AudioClip s_popHeavy; private static AudioClip s_popBoom; private const float ReadyVolume = 0.5f; private const float MaxReadyVolume = 0.7f; private static AudioClip s_ready; private static AudioClip s_readyMax; private static bool s_sfxSearched; private static readonly HashSet<string> s_failedWavs = new HashSet<string>(); internal static AudioSource PlayGlide(Player player) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_005f: 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) if ((Object)(object)s_glide == (Object)null) { s_glide = LoadWav("ghost_glide.wav"); } if ((Object)(object)s_glide == (Object)null) { return null; } if (!s_sfxSearched) { s_sfxGroup = FindSfxGroup(); } GameObject val = new GameObject("EnhancedVanillaWeapons_GlideSound"); val.transform.SetParent(((Component)player).transform, false); val.transform.localPosition = Vector3.up * 1f; AudioSource obj = val.AddComponent<AudioSource>(); obj.playOnAwake = false; obj.spatialBlend = 1f; obj.minDistance = 3f; obj.maxDistance = 30f; obj.outputAudioMixerGroup = s_sfxGroup; obj.clip = s_glide; obj.volume = 0.24f; obj.Play(); Object.Destroy((Object)(object)val, s_glide.length + 0.5f); return obj; } internal static void PlayPop(Vector3 position, int stacks) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) if (stacks <= 0) { return; } int num = Mathf.Clamp(stacks, 1, PopVolumes.Length) - 1; bool num2 = num == PopVolumes.Length - 1; if (num2 && (Object)(object)s_popFull == (Object)null) { s_popFull = LoadWav("rot_pop_full.wav"); } if (!num2 && (Object)(object)s_pop == (Object)null) { s_pop = LoadWav("rot_pop.wav"); } if (!num2) { PlayAt(s_pop, position, PopVolumes[num], PopPitches[num]); return; } float num3 = Mathf.InverseLerp(3f, 15f, (float)stacks); float num4 = Mathf.Lerp(PopPitches[num], 0.8f, num3); PlayAt(s_popFull, position, PopVolumes[num], num4); if (!(num3 <= 0f)) { PlayAt(s_popFull, position, 0.8f * num3, num4 * 1.04f); if ((Object)(object)s_popHeavy == (Object)null) { s_popHeavy = LoadWav("rot_pop_heavy.wav"); } PlayAt(s_popHeavy, position, 0.75f * num3, num4 * 0.94f / 0.8f); if ((Object)(object)s_popBoom == (Object)null) { s_popBoom = LoadWav("rot_pop_boom.wav"); } PlayAt(s_popBoom, position, 0.5f * num3, 1f); } } internal static void PlayReady(Vector3 position, int stacks) { //IL_0057: 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) if ((Object)(object)s_ready == (Object)null) { s_ready = LoadWav("rot_ready.wav"); } if ((Object)(object)s_readyMax == (Object)null) { s_readyMax = LoadWav("rot_ready_max.wav"); } float num = Mathf.InverseLerp(3f, 15f, (float)stacks); if (num < 1f) { PlayAt(s_ready, position, 0.5f * (1f - num), 1f); } if (num > 0f) { PlayAt(s_readyMax, position, 0.7f * num, 1f); } } private static void PlayAt(AudioClip clip, Vector3 position, float volume, float pitch) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown if (!((Object)(object)clip == (Object)null)) { if (!s_sfxSearched) { s_sfxGroup = FindSfxGroup(); } GameObject val = new GameObject("EnhancedVanillaWeapons_Sound"); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.playOnAwake = false; val2.spatialBlend = 1f; val2.minDistance = 3f; val2.maxDistance = 30f; val2.outputAudioMixerGroup = s_sfxGroup; val2.clip = clip; val2.volume = volume; val2.pitch = pitch; val2.Play(); Object.Destroy((Object)val, clip.length / val2.pitch + 0.5f); } } internal static void FadeOut(AudioSource source, float seconds) { if (!((Object)(object)source == (Object)null)) { s_fades.Add(new Fade { Source = source, StartVolume = source.volume, Seconds = Mathf.Max(0.01f, seconds) }); } } internal static void Update() { for (int num = s_fades.Count - 1; num >= 0; num--) { Fade fade = s_fades[num]; if ((Object)(object)fade.Source == (Object)null) { s_fades.RemoveAt(num); } else { fade.Progress += Time.deltaTime / fade.Seconds; if (fade.Progress >= 1f) { Object.Destroy((Object)(object)((Component)fade.Source).gameObject); s_fades.RemoveAt(num); } else { float num2 = 1f - fade.Progress; fade.Source.volume = fade.StartVolume * num2 * num2; } } } } private static AudioMixerGroup FindSfxGroup() { s_sfxSearched = true; ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab("sfx_perfect_dodge") : null); AudioSource val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<AudioSource>(true) : null); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)"No mixer group from sfx_perfect_dodge; mod sounds ignore the SFX volume."); } if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.outputAudioMixerGroup; } private static AudioClip LoadWav(string name) { if (s_failedWavs.Contains(name)) { return null; } try { using Stream stream = typeof(ModSounds).Assembly.GetManifestResourceStream("EnhancedVanillaWeapons.Sounds." + name); if (stream == null) { throw new FileNotFoundException("embedded resource missing", name); } using BinaryReader reader = new BinaryReader(stream); return ParseWav(reader, name); } catch (Exception ex) { Plugin.Log.LogError((object)("Couldn't load sound " + name + ": " + ex.Message)); s_failedWavs.Add(name); return null; } } private static AudioClip ParseWav(BinaryReader reader, string name) { if (new string(reader.ReadChars(4)) != "RIFF") { throw new InvalidDataException("not RIFF"); } reader.ReadInt32(); if (new string(reader.ReadChars(4)) != "WAVE") { throw new InvalidDataException("not WAVE"); } int num = 0; int num2 = 0; while (reader.BaseStream.Position < reader.BaseStream.Length) { string text = new string(reader.ReadChars(4)); int num3 = reader.ReadInt32(); if (text == "fmt ") { short num4 = reader.ReadInt16(); num = reader.ReadInt16(); num2 = reader.ReadInt32(); reader.ReadInt32(); reader.ReadInt16(); short num5 = reader.ReadInt16(); if (num4 != 1 || num5 != 16) { throw new InvalidDataException($"need 16-bit PCM, got format {num4}, {num5} bit"); } reader.BaseStream.Seek(num3 - 16, SeekOrigin.Current); continue; } if (text == "data") { int num6 = num3 / 2; float[] array = new float[num6]; for (int i = 0; i < num6; i++) { array[i] = (float)reader.ReadInt16() / 32768f; } AudioClip val = AudioClip.Create(name, num6 / num, num, num2, false); SetData.Invoke(val, new object[2] { array, 0 }); return val; } reader.BaseStream.Seek(num3 + (num3 & 1), SeekOrigin.Current); } throw new InvalidDataException("no data chunk"); } } [BepInPlugin("Iteravio.EnhancedVanillaWeapons", "EnhancedVanillaWeapons", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "Iteravio.EnhancedVanillaWeapons"; public const string PluginName = "EnhancedVanillaWeapons"; public const string PluginVersion = "1.1.0"; private const string SkollAndHatiSection = "Skoll and Hati"; private const string JotunBaneSection = "Jotun Bane"; internal static ManualLogSource Log; internal static ConfigEntry<bool> StrikeEnabled; internal static ConfigEntry<int> StrikeEitrCost; internal static ConfigEntry<int> StrikeStaminaCost; internal static ConfigEntry<float> StrikeBackstabMultiplier; internal static ConfigEntry<float> StrikeCooldownSeconds; internal static ConfigEntry<int> StrikeRangeMeters; internal static ConfigEntry<bool> BaneEnabled; internal static ConfigEntry<int> BaneBluntPerStack; internal static ConfigEntry<float> BanePoisonMultiplier; internal static ConfigEntry<float> BaneCloudRadius; internal static ConfigEntry<float> BaneCloudRadiusPerExtra; internal static ConfigEntry<int> BaneExtraPoison; internal static ConfigEntry<int> BaneExtraDotPercent; internal static ConfigEntry<int> BaneRuptureGrowthPercent; internal static ConfigEntry<bool> LogStrikes; internal static ConfigEntry<bool> LogBane; private const string SyncedTag = "[Synced with Server]"; private const string NotSyncedTag = "[Not synced with Server]"; private void Awake() { //IL_0311: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; StrikeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Skoll and Hati", "ShadowStrikeEnabled", true, Synced("The secondary attack turns you to smoke that quickly glides behind the enemy and stabs its back.", null, 6)); StrikeEitrCost = ((BaseUnityPlugin)this).Config.Bind<int>("Skoll and Hati", "ShadowStrikeEitrCost", 25, Synced("Shadow Strike eitr cost. If you have less eitr than this, the secondary attack stays as the vanilla leap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), 5)); StrikeStaminaCost = ((BaseUnityPlugin)this).Config.Bind<int>("Skoll and Hati", "ShadowStrikeStaminaCost", 20, Synced("Shadow Strike stamina cost (lowered by knife skill like any attack).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), 4)); StrikeBackstabMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Skoll and Hati", "ShadowStrikeBackstabMultiplier", 3f, Synced("Damage multiplier when a Shadow Strike lands as a sneak attack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), 3)); StrikeCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Skoll and Hati", "ShadowStrikeCooldownSeconds", 3f, Synced("Shadow Strike cooldown (seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), 2)); StrikeRangeMeters = ((BaseUnityPlugin)this).Config.Bind<int>("Skoll and Hati", "ShadowStrikeRangeMeters", 20, Synced("Shadow Strike range (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 30), 1)); BaneEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Jotun Bane", "PoisonStacksEnabled", true, Synced("Every hit adds a rot stack (up to 15), making the poison stronger, and keeps the stacks going for 8 more seconds.\n\nThe secondary attack ruptures the stacks, dealing all remaining poison at once plus extra poison & blunt damage per stack. A rupture of 3 or more releases a rot cloud that spreads stacks to nearby enemies.", null, 8)); BanePoisonMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Jotun Bane", "RupturePoisonMultiplier", 1.5f, Synced("How much harder the remaining poison hits when ruptured.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), 7)); BaneBluntPerStack = ((BaseUnityPlugin)this).Config.Bind<int>("Jotun Bane", "RuptureBluntPerStack", 20, Synced("Blunt damage a rupture deals per stack. Lands even on poison-immune enemies.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), 6)); BaneExtraPoison = ((BaseUnityPlugin)this).Config.Bind<int>("Jotun Bane", "RupturePoisonPerStack", 20, Synced("Extra poison damage a rupture deals per stack, on top of the stacked poison.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), 5)); BaneRuptureGrowthPercent = ((BaseUnityPlugin)this).Config.Bind<int>("Jotun Bane", "PercentRuptureDamageIncreasePerExtraStack", 2, Synced("How much bigger each stack past 3 makes the rupture's per-stack blunt and poison.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), 4)); BaneExtraDotPercent = ((BaseUnityPlugin)this).Config.Bind<int>("Jotun Bane", "PercentPoisonPerSecondIncreasePerExtraStack", 5, Synced("How much stronger the poison gets with each stack past 3.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), 2)); BaneCloudRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Jotun Bane", "RotCloudRadiusMeters", 7.5f, Synced("Rot cloud radius at 3 stacks (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), 1)); BaneCloudRadiusPerExtra = ((BaseUnityPlugin)this).Config.Bind<float>("Jotun Bane", "RotCloudRadiusMetersPerExtraStack", 1.5f, Synced("How much the rot cloud's radius grows per stack past 3 (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), 0)); LogStrikes = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogStrikes", false, "Log each Shadow Strike. Should be disabled, unless you are testing something? : D [Not synced with Server]"); LogBane = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogJotunBane", false, "Log Jotun Bane stacks and ruptures (on the machine that controls the enemy). Should be disabled, unless you are testing something? : D [Not synced with Server]"); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new StatusCommand()); new Harmony("Iteravio.EnhancedVanillaWeapons").PatchAll(); Log.LogInfo((object)("Ready: " + GetSettingsSummary())); } private void Update() { Glide.Update(); Ghosts.Update(); TunnelVision.Update(); ModSounds.Update(); JotunBane.Update(); } private static ConfigDescription Synced(string description, AcceptableValueBase range, int order) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown return new ConfigDescription(description + " [Synced with Server]", range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, Order = order, ShowRangeAsPercent = false } }); } internal static string GetSettingsSummary() { return (StrikeEnabled.Value ? ($"Shadow Strike on, {StrikeEitrCost.Value} eitr, {StrikeStaminaCost.Value} stamina, {StrikeBackstabMultiplier.Value:0.#}x backstab, " + $"{StrikeCooldownSeconds.Value:0.#} s cooldown, {StrikeRangeMeters.Value} m range") : "Shadow Strike off (vanilla leap)") + "; " + (BaneEnabled.Value ? ($"Jotun Bane stacks on, {BanePoisonMultiplier.Value:0.##}x rupture poison, {BaneBluntPerStack.Value} blunt and {BaneExtraPoison.Value} poison per stack, " + $"+{BaneRuptureGrowthPercent.Value}% rupture and +{BaneExtraDotPercent.Value}% poison per second per extra stack, {BaneCloudRadius.Value:0.#} m rot cloud (+{BaneCloudRadiusPerExtra.Value:0.#} m per extra stack)") : "Jotun Bane stacks off"); } internal static string GetSettingsSource() { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null) { return "local config"; } if (!instance.IsServer()) { return "synced from host"; } return "this machine (host/solo)"; } } internal class StatusCommand : ConsoleCommand { public override string Name => "enhancedvanillaweapons"; public override string Help => "Show EnhancedVanillaWeapons settings in effect and this session's Shadow Strike and Jotun Bane counts"; public override void Run(string[] args, Terminal context) { if (!((Object)(object)context == (Object)null)) { context.AddString("EnhancedVanillaWeapons 1.1.0"); context.AddString("Settings (" + Plugin.GetSettingsSource() + "): " + Plugin.GetSettingsSummary()); context.AddString($"This session: {ShadowStrike.Strikes} Shadow Strikes ({ShadowStrike.Hits} hit, {ShadowStrike.Misses} missed), {ShadowStrike.Fizzles} fizzles"); context.AddString($"This session: {JotunBane.Ruptures} Jotun Bane ruptures ({JotunBane.FullRuptures} at 3+ stacks, biggest {JotunBane.BiggestRupture})"); } } } internal static class ShadowStrike { private class HitDistanceComparer : IComparer<RaycastHit> { internal static readonly HitDistanceComparer Instance = new HitDistanceComparer(); public int Compare(RaycastHit a, RaycastHit b) { return ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance); } } private const string KnifeName = "$item_knife_skollandhati"; private const string SmokePrefab = "vfx_odin_despawn"; private const string ArrivalSound = "sfx_perfect_dodge"; private const float AimAssistRadius = 0.5f; private const float AimConeDegrees = 6f; private const float WindupHoldSpeed = 0.25f; private const float WindupArrivalSpeed = 10f; private const float FizzleInterval = 0.6f; private const float BehindGap = 0.5f; private const float MaxHeightDifference = 1.5f; private const float PreferredMaxUphill = 0.4f; private const float MaxGroundSlope = 50f; private const float SwingReachMargin = 0.6f; private const float MaxSwingReach = 5f; private const float CatchUpGap = 1.8f; private static readonly float[] SpotAngles = new float[5] { 0f, 35f, -35f, 70f, -70f }; internal static int Strikes; internal static int Fizzles; internal static int Hits; internal static int Misses; private static Attack s_activeAttack; private static Attack s_pendingAttack; private static Character s_pendingTarget; private static float s_pressTime; private static Vector3 s_armedSpot; private static float s_readyTime; private static float s_nextFizzleTime; private static Character s_strikeTarget; private static bool s_strikeLanded; private static string s_otherVictims = ""; private static int s_solidMask; private static int s_characterMask; private static readonly RaycastHit[] s_hits = (RaycastHit[])(object)new RaycastHit[32]; private static readonly Collider[] s_overlaps = (Collider[])(object)new Collider[32]; private static readonly FieldRef<Character, float> MaxAirAltitude = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude"); private const float LocalEffectLifetime = 8f; private static void InitMasks() { if (s_solidMask == 0) { s_solidMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "terrain", "blocker", "vehicle" }); s_characterMask = LayerMask.GetMask(new string[5] { "character", "character_net", "character_ghost", "hitbox", "character_noenv" }); } } internal static bool IsStrikeWeapon(ItemData weapon) { return weapon?.m_shared.m_name == "$item_knife_skollandhati"; } internal static bool HasEitrForStrike(Player player) { int value = Plugin.StrikeEitrCost.Value; if (value > 0) { if (((Character)player).GetMaxEitr() > 0f) { return ((Character)player).HaveEitr((float)value + 0.1f); } return false; } return true; } internal static Character TryArm(Player player) { if (Time.time < s_readyTime) { return Fizzle(player, "on cooldown"); } Character val = FindTarget(player); if ((Object)(object)val == (Object)null) { return Fizzle(player, "no target"); } if (!TryFindSpotBehind(player, val, out s_armedSpot, out var _)) { return Fizzle(player, "no safe spot behind " + val.m_name); } return val; } internal static void OnAttackStarted(Player player, Attack attack, Character target) { //IL_005a: 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) s_activeAttack = attack; s_pendingAttack = attack; s_pendingTarget = target; s_pressTime = Time.time; s_readyTime = Time.time + Plugin.StrikeCooldownSeconds.Value; ((Character)player).UseEitr((float)Plugin.StrikeEitrCost.Value); s_otherVictims = ""; Strikes++; Glide.Begin(player, target, s_armedSpot); if (Plugin.LogStrikes.Value) { Plugin.Log.LogInfo((object)$"Shadow Strike behind {target.m_name}, height difference {((Component)target).transform.position.y - s_armedSpot.y:0.0} m"); } } internal static void OnAttackUpdate(Attack attack, ZSyncAnimation zanim) { if (attack == s_pendingAttack && (Object)(object)zanim != (Object)null) { zanim.SetSpeed(Glide.Active ? 0.25f : 10f); } } internal static void BeforeAttackTrigger(Attack attack, ZSyncAnimation zanim) { if (attack != s_pendingAttack) { return; } Character val = s_pendingTarget; s_pendingAttack = null; s_pendingTarget = null; if (zanim != null) { zanim.SetSpeed(1f); } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { Glide.Finish(localPlayer); if (!((Object)(object)val == (Object)null) && !val.IsDead()) { CatchUp(localPlayer, val); FaceTarget(localPlayer, val); ShapeSwing(attack, localPlayer, val); s_strikeTarget = val; s_strikeLanded = false; } } } private static void CatchUp(Player player, Character target) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0045: Unknown result type (might be due to invalid IL or missing references) CapsuleCollider collider = target.GetCollider(); Vector3 centerPoint = ((Character)player).GetCenterPoint(); Vector3 val = (((Object)(object)collider != (Object)null) ? ((Collider)collider).ClosestPoint(centerPoint) : target.GetCenterPoint()); if (!(Vector3.Distance(centerPoint, val) <= 1.8f) && TryFindSpotBehind(player, target, out var spot, out var _)) { Teleport(player, spot, target); if (Plugin.LogStrikes.Value) { Plugin.Log.LogInfo((object)("Caught up with " + target.m_name + " before the stab")); } } } private static void ShapeSwing(Attack attack, Player player, Character target) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0039: 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) attack.m_hitTerrain = false; attack.m_maxYAngle = 90f; CapsuleCollider collider = target.GetCollider(); Vector3 centerPoint = ((Character)player).GetCenterPoint(); Vector3 val = (((Object)(object)collider != (Object)null) ? ((Collider)collider).ClosestPoint(centerPoint) : target.GetCenterPoint()); float num = Vector3.Distance(centerPoint, val) + 0.6f; attack.m_attackRange = Mathf.Clamp(num, attack.m_attackRange, 5f); } internal static void AfterAttackTrigger() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) Character val = s_strikeTarget; if ((Object)(object)val == (Object)null) { return; } s_strikeTarget = null; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { if (s_strikeLanded) { Hits++; } else { Misses++; } if (Plugin.LogStrikes.Value) { float num = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val).transform.position) - val.GetRadius(); string arg = (s_strikeLanded ? "" : ((s_otherVictims.Length > 0) ? (", struck " + s_otherVictims + " instead") : ", struck no creature")); Plugin.Log.LogInfo((object)(string.Format("{0} {1} {2:0.00} s after the press, ", s_strikeLanded ? "Hit" : "MISSED", val.m_name, Time.time - s_pressTime) + $"{num:0.0} m from its edge, height difference {((Component)val).transform.position.y - ((Component)localPlayer).transform.position.y:0.0} m{arg}")); } } } internal static void OnDamage(Character victim, HitData hit) { if (!((Object)(object)s_strikeTarget == (Object)null) && !((Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer)) { if (hit.m_backstabBonus > 1f) { hit.m_backstabBonus = Plugin.StrikeBackstabMultiplier.Value; } if ((Object)(object)victim == (Object)(object)s_strikeTarget) { s_strikeLanded = true; } else { s_otherVictims = s_otherVictims + ((s_otherVictims.Length > 0) ? ", " : "") + victim.m_name; } } } internal static void OnAttackStop(Attack attack) { if (attack == s_activeAttack) { s_activeAttack = null; s_pendingAttack = null; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Glide.Finish(localPlayer); } } } internal static bool SuppressesMovement(Character character) { if (s_activeAttack != null && (Object)(object)character == (Object)(object)Player.m_localPlayer) { return !s_activeAttack.IsDone(); } return false; } private static Character Fizzle(Player player, string reason) { if (Time.time < s_nextFizzleTime) { return null; } s_nextFizzleTime = Time.time + 0.6f; Fizzles++; if (Plugin.LogStrikes.Value) { Plugin.Log.LogInfo((object)("Fizzle: " + reason)); } return null; } internal static void FaceTarget(Player player, Character target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_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_0046: 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_005d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target.GetCenterPoint() - ((Character)player).GetCenterPoint(); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(val.x, 0f, val.z); if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f)) { Quaternion rotation = Quaternion.LookRotation(val2); ((Component)player).transform.rotation = rotation; Rigidbody component = ((Component)player).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.rotation = rotation; } ((Character)player).SetLookDir(val, 0f); } } private static Character FindTarget(Player player) { //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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } InitMasks(); float num = Plugin.StrikeRangeMeters.Value; Vector3 position = ((Component)instance).transform.position; Vector3 forward = ((Component)instance).transform.forward; float num2 = Vector3.Distance(position, ((Character)player).GetEyePoint()) + num + 2f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(position, forward, ref val, num2, s_solidMask, (QueryTriggerInteraction)1)) { num2 = ((RaycastHit)(ref val)).distance; } int num3 = Physics.SphereCastNonAlloc(position, 0.5f, forward, s_hits, num2, s_characterMask, (QueryTriggerInteraction)1); Array.Sort(s_hits, 0, num3, HitDistanceComparer.Instance); for (int i = 0; i < num3; i++) { Character componentInParent = ((Component)((RaycastHit)(ref s_hits[i])).collider).GetComponentInParent<Character>(); if (IsValidTarget(player, componentInParent, num)) { return componentInParent; } } Character val2 = null; float num4 = 6f; foreach (Character allCharacter in Character.GetAllCharacters()) { if (IsValidTarget(player, allCharacter, num)) { Vector3 centerPoint = allCharacter.GetCenterPoint(); float num5 = Vector3.Angle(forward, centerPoint - position); if (!(num5 >= num4) && !Physics.Linecast(position, centerPoint, s_solidMask, (QueryTriggerInteraction)1)) { val2 = allCharacter; num4 = num5; } } } if ((Object)(object)val2 == (Object)null && Plugin.LogStrikes.Value) { LogNearestMiss(player, position, forward); } return val2; } private static void LogNearestMiss(Player player, Vector3 origin, Vector3 direction) { //IL_0094: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0045: Unknown result type (might be due to invalid IL or missing references) Character val = null; float num = 30f; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)(object)player) && !allCharacter.IsDead() && BaseAI.IsEnemy((Character)(object)player, allCharacter)) { float num2 = Vector3.Angle(direction, allCharacter.GetCenterPoint() - origin); if (!(num2 >= num)) { val = allCharacter; num = num2; } } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogInfo((object)"No target: no enemy within 30° of the crosshair"); return; } float num3 = Vector3.Distance(((Component)player).transform.position, ((Component)val).transform.position) - val.GetRadius(); bool flag = Physics.Linecast(origin, val.GetCenterPoint(), s_solidMask, (QueryTriggerInteraction)1); Plugin.Log.LogInfo((object)string.Format("No target: nearest enemy {0} {1:0.0}° off the crosshair, {2:0.0} m away{3}", val.m_name, num, num3, flag ? ", behind cover" : "")); } private static bool IsValidTarget(Player player, Character character, float range) { //IL_0029: 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) if ((Object)(object)character != (Object)null && (Object)(object)character != (Object)(object)player && !character.IsDead() && BaseAI.IsEnemy((Character)(object)player, character)) { return Vector3.Distance(((Component)player).transform.position, ((Component)character).transform.position) <= range + character.GetRadius(); } return false; } internal static bool TryFindSpotBehind(Player player, Character target, out Vector3 spot, out Vector3 facing) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing referenc