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 WaysOfTheGods v1.0.1
WaysOfTheGods.dll
Decompiled 9 hours 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.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("WaysOfTheGods")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("WaysOfTheGods")] [assembly: AssemblyTitle("WaysOfTheGods")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ClassiDiValheim { public class SpellDef { public string Name; public int UnlockLevel; public float Cooldown; public float StaminaCost; public string IconItem; public Action<Player, int> CastAction; public Func<int, string> Describe; } public static class Abilities { private static readonly Dictionary<string, float> CooldownEnd = new Dictionary<string, float>(); public static bool DebugUnlockAll; public static readonly SpellDef[] MageSpells = new SpellDef[8] { new SpellDef { Name = "Fireball", UnlockLevel = 10, Cooldown = 6f, StaminaCost = 20f, IconItem = "StaffFireball", CastAction = CastFireball, Describe = (int lvl) => $"Hurl a fireball ({FireballDamage(lvl)} damage)" }, new SpellDef { Name = "Frost Nova", UnlockLevel = 20, Cooldown = 15f, StaminaCost = 30f, IconItem = "FreezeGland", CastAction = CastFrostNova, Describe = (int lvl) => $"Explosion of frost around you ({FrostNovaDamage(lvl)} damage, 8 m)" }, new SpellDef { Name = "Ice Shards", UnlockLevel = 30, Cooldown = 10f, StaminaCost = 30f, IconItem = "StaffIceShards", CastAction = CastIceShards, Describe = (int lvl) => $"Fan of 5 freezing shards ({IceShardDamage(lvl)} damage each)" }, new SpellDef { Name = "Lightning Bolt", UnlockLevel = 40, Cooldown = 12f, StaminaCost = 35f, IconItem = "StaffLightning", CastAction = CastLightningBolt, Describe = (int lvl) => $"Crackling projectile ({LightningBoltDamage(lvl)} damage)" }, new SpellDef { Name = "Ring of Fire", UnlockLevel = 50, Cooldown = 20f, StaminaCost = 45f, IconItem = "SurtlingCore", CastAction = CastRingOfFire, Describe = (int lvl) => $"12 fireballs in every direction ({RingFireDamage(lvl)} damage each)" }, new SpellDef { Name = "Rune Shield", UnlockLevel = 60, Cooldown = 60f, StaminaCost = 40f, IconItem = "StaffShield", CastAction = CastRuneShield, Describe = (int lvl) => "Protective dome (8 m, 20 s): armors whoever is inside, dissolves projectiles and repels enemies" }, new SpellDef { Name = "Lightning Storm", UnlockLevel = 70, Cooldown = 30f, StaminaCost = 60f, IconItem = "Thunderstone", CastAction = CastLightningStorm, Describe = (int lvl) => $"8 bolts strike nearby enemies ({StormBoltDamage(lvl)} damage each)" }, new SpellDef { Name = "Wrath of the Gods", UnlockLevel = 80, Cooldown = 60f, StaminaCost = 80f, IconItem = "GoblinTotem", CastAction = CastWrathOfTheGods, Describe = (int lvl) => $"Meteor rain in front of you ({MeteorDamage(lvl)} damage each)" } }; public static readonly SpellDef[] BerserkerSpells = new SpellDef[8] { new SpellDef { Name = "War Cry", UnlockLevel = 10, Cooldown = 10f, StaminaCost = 15f, IconItem = "Club", CastAction = CastWarCry, Describe = (int lvl) => $"Repels and damages nearby enemies ({WarCryDamage(lvl)} damage, 6 m)" }, new SpellDef { Name = "Charge", UnlockLevel = 20, Cooldown = 8f, StaminaCost = 20f, IconItem = "ShieldWood", CastAction = CastCharge, Describe = (int lvl) => $"Forward dash that tramples enemies ({ChargeDamage(lvl)} damage)" }, new SpellDef { Name = "Spear Throw", UnlockLevel = 30, Cooldown = 6f, StaminaCost = 20f, IconItem = "SpearBronze", CastAction = CastSpearThrow, Describe = (int lvl) => $"Hurl an ancient spear ({SpearDamage(lvl)} damage)" }, new SpellDef { Name = "Seismic Blow", UnlockLevel = 40, Cooldown = 15f, StaminaCost = 30f, IconItem = "SledgeIron", CastAction = CastSeismicBlow, Describe = (int lvl) => $"Make the earth tremble ({SeismicDamage(lvl)} damage, 8 m)" }, new SpellDef { Name = "Berserker Fury", UnlockLevel = 50, Cooldown = 45f, StaminaCost = 30f, IconItem = "TrophyWolf", CastAction = CastFury, Describe = (int lvl) => "+40% damage and nearly free attacks for 15 seconds" }, new SpellDef { Name = "Iron Skin", UnlockLevel = 60, Cooldown = 60f, StaminaCost = 30f, IconItem = "ArmorIronChest", CastAction = CastIronSkin, Describe = (int lvl) => "Your skin turns to iron: massive defense for 20 seconds" }, new SpellDef { Name = "Whirlwind", UnlockLevel = 70, Cooldown = 25f, StaminaCost = 45f, IconItem = "SwordIron", CastAction = CastWhirlwind, Describe = (int lvl) => $"Spinning blades for 3 seconds ({WhirlwindDamage(lvl)} damage per hit, 4 m)" }, new SpellDef { Name = "Titanic Slam", UnlockLevel = 80, Cooldown = 60f, StaminaCost = 60f, IconItem = "SledgeDemolisher", CastAction = CastTitanicSlam, Describe = (int lvl) => $"Leap skyward and crash down ({SlamDamage(lvl)} damage, 10 m)" } }; public static readonly SpellDef[] NecromancerSpells = new SpellDef[8] { new SpellDef { Name = "Life Drain", UnlockLevel = 10, Cooldown = 8f, StaminaCost = 20f, IconItem = "Bloodbag", CastAction = CastLifeDrain, Describe = (int lvl) => $"Drain the life of nearby enemies ({DrainDamage(lvl)} damage, heals you per enemy hit)" }, new SpellDef { Name = "Summon Skeleton", UnlockLevel = 20, Cooldown = 10f, StaminaCost = 30f, IconItem = "TrophySkeleton", CastAction = CastSummonSkeleton, Describe = (int lvl) => $"Raise a skeleton that fights for you (max {MaxSkeletons(lvl)})" }, new SpellDef { Name = "Ooze Bomb", UnlockLevel = 30, Cooldown = 8f, StaminaCost = 25f, IconItem = "Ooze", CastAction = CastOozeBomb, Describe = (int lvl) => $"Throw a bomb that bursts into a poison cloud ({OozeDamage(lvl)} poison damage)" }, new SpellDef { Name = "Toxic Cloud", UnlockLevel = 40, Cooldown = 20f, StaminaCost = 40f, IconItem = "Guck", CastAction = CastToxicCloud, Describe = (int lvl) => $"Bonemass miasma in front of you: 6 waves of poison ({ToxicTickDamage(lvl)} damage each, 6 m)" }, new SpellDef { Name = "Spectral Wave", UnlockLevel = 50, Cooldown = 18f, StaminaCost = 45f, IconItem = "Entrails", CastAction = CastSpectralWave, Describe = (int lvl) => $"Wave of spirits that rends and repels ({SpectralDamage(lvl)} damage, 8 m)" }, new SpellDef { Name = "Bone Armor", UnlockLevel = 60, Cooldown = 60f, StaminaCost = 30f, IconItem = "BoneFragments", CastAction = CastBoneArmor, Describe = (int lvl) => "Ancient bones armor you for 20 seconds" }, new SpellDef { Name = "Putrid Rain", UnlockLevel = 70, Cooldown = 30f, StaminaCost = 60f, IconItem = "BombOoze", CastAction = CastPutridRain, Describe = (int lvl) => $"8 ooze bombs rain down in front of you ({OozeDamage(lvl)} poison damage each)" }, new SpellDef { Name = "Army of the Dead", UnlockLevel = 80, Cooldown = 90f, StaminaCost = 80f, IconItem = "TrophyDraugrElite", CastAction = CastArmyOfTheDead, Describe = (int lvl) => $"4 skeletons rise from the ground plus a spectral blast ({SpectralDamage(lvl)} damage, 10 m)" } }; private static readonly List<Character> Minions = new List<Character>(); public static SpellDef[] GetSpells(PlayerClass cls) { return cls switch { PlayerClass.Mage => MageSpells, PlayerClass.Berserker => BerserkerSpells, PlayerClass.Necromancer => NecromancerSpells, _ => new SpellDef[0], }; } private static int FireballDamage(int lvl) { return 20 + (int)(1.5f * (float)lvl); } private static int FrostNovaDamage(int lvl) { return 15 + (int)(1.2f * (float)lvl); } private static int IceShardDamage(int lvl) { return 10 + (int)(0.8f * (float)lvl); } private static int LightningBoltDamage(int lvl) { return 30 + 2 * lvl; } private static int RingFireDamage(int lvl) { return 15 + lvl; } private static int StormBoltDamage(int lvl) { return 25 + (int)(1.5f * (float)lvl); } private static int MeteorDamage(int lvl) { return 60 + 2 * lvl; } private static int WarCryDamage(int lvl) { return 10 + (int)(0.8f * (float)lvl); } private static int ChargeDamage(int lvl) { return 15 + lvl; } private static int SpearDamage(int lvl) { return 25 + (int)(1.8f * (float)lvl); } private static int SeismicDamage(int lvl) { return 30 + (int)(1.6f * (float)lvl); } private static int WhirlwindDamage(int lvl) { return 12 + lvl; } private static int SlamDamage(int lvl) { return 50 + 2 * lvl; } private static int DrainDamage(int lvl) { return 12 + lvl; } private static int DrainHeal(int lvl) { return 5 + (int)(0.3f * (float)lvl); } private static int OozeDamage(int lvl) { return 20 + (int)(1.5f * (float)lvl); } private static int ToxicTickDamage(int lvl) { return 8 + (int)(0.6f * (float)lvl); } private static int SpectralDamage(int lvl) { return 20 + (int)(1.5f * (float)lvl); } private static int MaxSkeletons(int lvl) { return Mathf.Clamp(1 + lvl / 20, 1, 5); } public static IEnumerable<string> GetUnlockedAt(PlayerClass cls, int level) { return from s in GetSpells(cls) where s.UnlockLevel == level select s.Name; } public static float GetCooldownRemaining(string spellName) { float value; return CooldownEnd.TryGetValue(spellName, out value) ? Mathf.Max(0f, value - Time.time) : 0f; } public static bool IsUnlocked(Player player, SpellDef spell) { int num = (DebugUnlockAll ? 80 : ClassSystem.GetLevel(player)); return num >= spell.UnlockLevel; } public static void CastSpell(Player player, int index) { SpellDef[] spells = GetSpells(ClassSystem.GetClass(player)); if (index < 0 || index >= spells.Length) { return; } SpellDef spellDef = spells[index]; int level = ClassSystem.GetLevel(player); if (!IsUnlocked(player, spellDef)) { ((Character)player).Message((MessageType)1, $"{spellDef.Name} unlocks at level {spellDef.UnlockLevel}", 0, (Sprite)null); return; } float cooldownRemaining = GetCooldownRemaining(spellDef.Name); if (cooldownRemaining > 0f) { ((Character)player).Message((MessageType)1, $"{spellDef.Name} on cooldown ({cooldownRemaining:0}s)", 0, (Sprite)null); return; } if (!((Character)player).HaveStamina(spellDef.StaminaCost)) { ((Character)player).Message((MessageType)1, "Not enough stamina", 0, (Sprite)null); return; } ((Character)player).UseStamina(spellDef.StaminaCost); spellDef.CastAction(player, level); CooldownEnd[spellDef.Name] = Time.time + spellDef.Cooldown; } private static void CastFireball(Player player, int level) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "throw_bomb", "throw", "spear_throw", "staff_fireball0", "gpower"); HitData val = new HitData(); val.m_damage.m_fire = FireballDamage(level); val.m_pushForce = 40f; val.SetAttacker((Character)(object)player); LaunchProjectile(player, "Imp_fireball_projectile", AimDirection(player), 25f, val); Effects.TryPlayAt(EyePosition(player), "sfx_imp_fireball_launch"); } private static void CastFrostNova(Player player, int level) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "gpower"); int num = DamageEnemiesAround(player, ((Component)player).transform.position, 8f, delegate(HitData hit) { hit.m_damage.m_frost = FrostNovaDamage(level); }, 80f, new string[1] { "fx_iceshard_hit" }); Effects.TryPlayAt(((Component)player).transform.position, "fx_fenring_icenova"); ((Character)player).Message((MessageType)1, (num > 0) ? $"Frost Nova: {num} enemies hit" : "Frost Nova: no enemies in range", 0, (Sprite)null); } private static void CastIceShards(Player player, int level) { //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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0089: 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) Effects.TryCastAnimation(player, "staff_rapidfire", "gpower"); Vector3 val = AimDirection(player); float[] array = new float[5] { -20f, -10f, 0f, 10f, 20f }; foreach (float num in array) { Vector3 dir = Quaternion.AngleAxis(num, Vector3.up) * val; HitData val2 = new HitData(); val2.m_damage.m_frost = IceShardDamage(level); val2.m_pushForce = 20f; val2.SetAttacker((Character)(object)player); LaunchProjectile(player, "staff_iceshard_projectile", dir, 30f, val2); } Effects.TryPlayAt(EyePosition(player), "fx_iceshard_launch"); } private static void CastLightningBolt(Player player, int level) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0050: 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) Effects.TryCastAnimation(player, "staff_lightningshot", "gpower"); HitData val = new HitData(); val.m_damage.m_lightning = LightningBoltDamage(level); val.m_pushForce = 60f; val.SetAttacker((Character)(object)player); LaunchProjectile(player, "staff_lightning_projectile", AimDirection(player), 35f, val); Effects.TryPlayAt(EyePosition(player), "vfx_lightningstaff_fire"); } private static void CastRingOfFire(Player player, int level) { //IL_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_006f: 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) Effects.TryCastAnimation(player, "gpower"); for (int i = 0; i < 12; i++) { Vector3 dir = Quaternion.AngleAxis((float)i * 30f, Vector3.up) * ((Component)player).transform.forward; HitData val = new HitData(); val.m_damage.m_fire = RingFireDamage(level); val.m_pushForce = 40f; val.SetAttacker((Character)(object)player); LaunchProjectile(player, "Imp_fireball_projectile", dir, 20f, val); } Effects.TryPlayAt(((Component)player).transform.position, "sfx_imp_fireball_launch"); } private static void CastRuneShield(Player player, int level) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "staff_shield", "gpower"); Vector3 position = ((Component)player).transform.position; GameObject val = new GameObject("cdv_rune_dome"); val.transform.position = position; RuneDome runeDome = val.AddComponent<RuneDome>(); runeDome.Owner = player; runeDome.Radius = 8f; runeDome.EndTime = Time.time + 20f; GameObject val2 = Effects.FindPrefab("vfx_StaffShield"); if ((Object)(object)val2 != (Object)null) { GameObject val3 = Object.Instantiate<GameObject>(val2, position, Quaternion.identity, val.transform); MonoBehaviour[] componentsInChildren = val3.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val4 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val4); } val3.transform.localScale = Vector3.one * 5.6f; } Effects.TryPlayAt(position, 4f, "fx_StaffShield_Hit"); } private static void CastLightningStorm(Player player, int level) { Effects.TryCastAnimation(player, "staff_summon", "gpower"); ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(LightningStorm(player, level)); } private static IEnumerator LightningStorm(Player player, int level) { for (int i = 0; i < 8; i++) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } List<Character> enemies = EnemiesAround(((Component)player).transform.position, 12f); Vector3 point; if (enemies.Count > 0) { point = ((Component)enemies[Random.Range(0, enemies.Count)]).transform.position; } else { Vector2 offset = Random.insideUnitCircle * 8f; point = ((Component)player).transform.position + new Vector3(offset.x, 0f, offset.y); } SpawnLightningBolt(player, point, level); yield return (object)new WaitForSeconds(0.5f); } } private static void SpawnLightningBolt(Player player, Vector3 point, int level) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) GameObject val = Effects.FindPrefab("lightningAOE"); if ((Object)(object)val != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(val, point, Quaternion.identity); Aoe[] componentsInChildren = val2.GetComponentsInChildren<Aoe>(true); foreach (Aoe val3 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val3); } Object.Destroy((Object)(object)val2, 4f); } Effects.TryPlayAt(point, 6f, "sfx_thunder"); DamageEnemiesAround(player, point, 3f, delegate(HitData hit) { hit.m_damage.m_lightning = StormBoltDamage(level); }, 60f, null); } private static void CastWrathOfTheGods(Player player, int level) { Effects.TryCastAnimation(player, "gpower"); ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(MeteorRain(player, level)); } private static IEnumerator MeteorRain(Player player, int level) { Vector3 center = ((Component)player).transform.position + ((Component)player).transform.forward * 8f; Effects.TryPlayAt(((Component)player).transform.position, "sfx_fader_meteor_start"); for (int i = 0; i < 10; i++) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } Vector2 offset = Random.insideUnitCircle * 6f; Vector3 target = center + new Vector3(offset.x, 0f, offset.y); Vector2 lateral = Random.insideUnitCircle * 3f; Vector3 spawn = target + new Vector3(lateral.x, 22f, lateral.y); Vector3 val = target - spawn; Vector3 dir = ((Vector3)(ref val)).normalized; HitData hit = new HitData(); hit.m_damage.m_fire = MeteorDamage(level); hit.m_damage.m_blunt = 20f; hit.m_pushForce = 100f; hit.SetAttacker((Character)(object)player); GameObject prefab = Effects.FindPrefab("projectile_meteor", "projectile_meteor_fader"); if ((Object)(object)prefab != (Object)null) { GameObject go = Object.Instantiate<GameObject>(prefab, spawn, Quaternion.LookRotation(dir)); SetupProjectile(go, player, dir * 28f, hit); } yield return (object)new WaitForSeconds(0.35f); } } private static void CastWarCry(Player player, int level) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "emote_challenge", "challenge", "gpower"); int num = DamageEnemiesAround(player, ((Component)player).transform.position, 6f, delegate(HitData hit) { hit.m_damage.m_blunt = WarCryDamage(level); }, 150f, new string[1] { "vfx_clubhit" }); Effects.TryPlayAt(((Component)player).transform.position, "fx_eikthyr_stomp"); ((Character)player).Message((MessageType)1, (num > 0) ? $"War Cry: {num} enemies repelled" : "War Cry: no enemies in range", 0, (Sprite)null); } private static void CastCharge(Player player, int level) { Effects.TryCastAnimation(player, "sword_secondary", "unarmed_kick"); ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(ChargeDash(player, level)); } private static IEnumerator ChargeDash(Player player, int level) { Vector3 dir = ((Component)player).transform.forward; dir.y = 0f; dir = ((Vector3)(ref dir)).normalized; HashSet<Character> alreadyHit = new HashSet<Character>(); float end = Time.time + 0.5f; bool first = true; while (Time.time < end && (Object)(object)player != (Object)null && !((Character)player).IsDead()) { yield return (object)new WaitForFixedUpdate(); if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { yield break; } Vector3 velocity = dir * 16f; velocity.y = (first ? 3f : ((Character)player).m_body.linearVelocity.y); ((Character)player).m_body.linearVelocity = velocity; ((Character)player).m_body.MovePosition(((Character)player).m_body.position + dir * 16f * Time.fixedDeltaTime); ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; first = false; foreach (Character enemy in EnemiesAround(((Component)player).transform.position, 2.5f)) { if (alreadyHit.Add(enemy)) { HitData hit = new HitData(); hit.m_damage.m_blunt = ChargeDamage(level); hit.m_pushForce = 90f; hit.m_point = ((Component)enemy).transform.position; hit.m_dir = dir; hit.SetAttacker((Character)(object)player); enemy.Damage(hit); Effects.TryPlayAt(((Component)enemy).transform.position + Vector3.up, "vfx_HitSparks"); } } } if (!((Object)(object)player == (Object)null) && !((Character)player).IsDead()) { Effects.TryCastAnimation(player, "sword_secondary", "unarmed_kick"); Vector3 finisherCenter = ((Component)player).transform.position + dir * 1.5f; int finisherHits = DamageEnemiesAround(player, finisherCenter, 2.5f, delegate(HitData val) { val.m_damage.m_blunt = (float)ChargeDamage(level) * 1.5f; }, 120f, new string[1] { "vfx_clubhit" }); if (finisherHits > 0) { ((Character)player).Message((MessageType)1, $"Charge: finishing blow on {finisherHits} enemies", 0, (Sprite)null); } } } private static void CastSpearThrow(Player player, int level) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "spear_throw", "throw", "swing_longsword0"); HitData val = new HitData(); val.m_damage.m_pierce = SpearDamage(level); val.m_pushForce = 60f; val.SetAttacker((Character)(object)player); LaunchProjectile(player, "ancientbarkspear_projectile", AimDirection(player), 32f, val, "bronzespear_projectile"); } private static void CastSeismicBlow(Player player, int level) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "swing_sledge", "battleaxe_attack0", "gpower"); int num = DamageEnemiesAround(player, ((Component)player).transform.position, 8f, delegate(HitData hit) { hit.m_damage.m_blunt = SeismicDamage(level); }, 100f, new string[1] { "vfx_clubhit" }); Effects.TryPlayAt(((Component)player).transform.position, "vfx_gdking_stomp"); Effects.TryPlayAt(((Component)player).transform.position, "sfx_gdking_stomp"); ((Character)player).Message((MessageType)1, (num > 0) ? $"Seismic Blow: {num} enemies hit" : "Seismic Blow: no enemies in range", 0, (Sprite)null); } private static void CastFury(Player player, int level) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "emote_roar", "roar", "emote_challenge"); PassiveEffects.ApplyTimedEffect(player, "SE_CDV_Furia"); Effects.TryPlayAt(((Component)player).transform.position, "sfx_trollfire_roar"); } private static void CastIronSkin(Player player, int level) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "emote_flex", "flex", "gpower"); PassiveEffects.ApplyTimedEffect(player, "SE_CDV_Ferro"); Effects.TryPlayAt(((Component)player).transform.position, "fx_StaffShield_Hit"); } private static void CastWhirlwind(Player player, int level) { ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(Whirlwind(player, level)); } private static IEnumerator Whirlwind(Player player, int level) { for (int i = 0; i < 6; i++) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } Effects.TryCastAnimation(player, "atgeir_secondary", "battleaxe_attack0", "swing_longsword0", "swing_axe0", "atgeir_attack0", "sword_secondary", "unarmed_attack0"); DamageEnemiesAround(player, ((Component)player).transform.position, 4f, delegate(HitData hit) { hit.m_damage.m_slash = WhirlwindDamage(level); }, 40f, new string[1] { "vfx_HitSparks" }); yield return (object)new WaitForSeconds(0.5f); } } private static void CastTitanicSlam(Player player, int level) { ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(TitanSlam(player, level)); } private static IEnumerator TitanSlam(Player player, int level) { float launchEnd = Time.time + 0.25f; while (Time.time < launchEnd && (Object)(object)player != (Object)null && !((Character)player).IsDead()) { yield return (object)new WaitForFixedUpdate(); if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { yield break; } ((Character)player).m_body.linearVelocity = ((Component)player).transform.forward * 6f + Vector3.up * 14f; ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; } yield return (object)new WaitForSeconds(0.15f); float timeout = Time.time + 3f; while (Time.time < timeout && (Object)(object)player != (Object)null && !((Character)player).IsDead() && !((Character)player).IsOnGround()) { ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; yield return null; } if (!((Object)(object)player == (Object)null) && !((Character)player).IsDead()) { ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; int hits = DamageEnemiesAround(player, ((Component)player).transform.position, 10f, delegate(HitData hit) { hit.m_damage.m_blunt = SlamDamage(level); }, 150f, new string[1] { "vfx_clubhit" }); Effects.TryPlayAt(((Component)player).transform.position, "fx_fader_meteor_hit"); Effects.TryPlayAt(((Component)player).transform.position, "vfx_gdking_stomp"); Effects.TryPlayAt(((Component)player).transform.position, "sfx_gdking_stomp"); ((Character)player).Message((MessageType)1, (hits > 0) ? $"Titanic Slam: {hits} enemies hit" : "Titanic Slam!", 0, (Sprite)null); } } private static void CastLifeDrain(Player player, int level) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "gpower"); int num = DamageEnemiesAround(player, ((Component)player).transform.position, 6f, delegate(HitData hit) { hit.m_damage.m_spirit = DrainDamage(level); }, 20f, new string[1] { "vfx_HitSparks" }); if (num > 0) { ((Character)player).Heal((float)(DrainHeal(level) * num), true); Effects.TryPlayAt(((Component)player).transform.position, "vfx_Potion_health_medium"); ((Character)player).Message((MessageType)1, $"Life Drain: {num} souls drained", 0, (Sprite)null); } else { ((Character)player).Message((MessageType)1, "Life Drain: no enemies in range", 0, (Sprite)null); } } private static void CastSummonSkeleton(Player player, int level) { Effects.TryCastAnimation(player, "staff_summon", "gpower"); SummonSkeleton(player, level); } private static void SummonSkeleton(Player player, int level) { //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_000a: 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_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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized * 2f; Vector3 position = ((Component)player).transform.position + new Vector3(val.x, 0.2f, val.y); Character val2 = SpawnMinion(player, "Skeleton_Friendly", position); if (!((Object)(object)val2 == (Object)null)) { Minions.RemoveAll((Character m) => (Object)(object)m == (Object)null || m.IsDead()); Minions.Add(val2); int num = MaxSkeletons(level); while (Minions.Count > num) { DespawnMinion(Minions[0]); Minions.RemoveAt(0); } Effects.TryPlayAt(position, "fx_summon_skeleton_spawn", "fx_summon_skeleton"); Effects.TryPlayAt(position, "sfx_skull_summon_skeleton"); } } private static void CastOozeBomb(Player player, int level) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "throw_bomb", "spear_throw"); HitData val = new HitData(); val.m_damage.m_poison = OozeDamage(level); val.m_pushForce = 30f; val.SetAttacker((Character)(object)player); LaunchProjectile(player, "oozebomb_projectile", AimDirection(player) + Vector3.up * 0.15f, 18f, val); } private static void CastToxicCloud(Player player, int level) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "gpower"); Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * 5f; Effects.TryPlayAt(val, 10f, "fx_Bonemass_aoe_start"); ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(ToxicCloud(player, val, level)); } private static IEnumerator ToxicCloud(Player player, Vector3 center, int level) { //IL_000e: 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) for (int i = 0; i < 6; i++) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } DamageEnemiesAround(player, center, 6f, delegate(HitData hit) { hit.m_damage.m_poison = ToxicTickDamage(level); }, 0f, null); yield return (object)new WaitForSeconds(1f); } } private static void CastSpectralWave(Player player, int level) { //IL_0032: 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) Effects.TryCastAnimation(player, "staff_summon", "gpower"); int num = DamageEnemiesAround(player, ((Component)player).transform.position, 8f, delegate(HitData hit) { hit.m_damage.m_spirit = SpectralDamage(level); hit.m_damage.m_slash = (float)SpectralDamage(level) / 2f; }, 120f, new string[2] { "fx_charred_summoned_death", "vfx_HitSparks" }); Effects.TryPlayAt(((Component)player).transform.position, "vfx_gdking_stomp"); ((Character)player).Message((MessageType)1, (num > 0) ? $"Spectral Wave: {num} enemies hit" : "Spectral Wave: no enemies in range", 0, (Sprite)null); } private static void CastBoneArmor(Player player, int level) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "gpower"); PassiveEffects.ApplyTimedEffect(player, "SE_CDV_Ossa"); Effects.TryPlayAt(((Component)player).transform.position, "fx_StaffShield_Hit"); } private static void CastPutridRain(Player player, int level) { Effects.TryCastAnimation(player, "staff_summon", "gpower"); ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(PutridRain(player, level)); } private static IEnumerator PutridRain(Player player, int level) { Vector3 center = ((Component)player).transform.position + ((Component)player).transform.forward * 8f; for (int i = 0; i < 8; i++) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } Vector2 offset = Random.insideUnitCircle * 5f; Vector3 target = center + new Vector3(offset.x, 0f, offset.y); Vector2 lateral = Random.insideUnitCircle * 2f; Vector3 spawn = target + new Vector3(lateral.x, 18f, lateral.y); Vector3 val = target - spawn; Vector3 dir = ((Vector3)(ref val)).normalized; HitData hit = new HitData(); hit.m_damage.m_poison = OozeDamage(level); hit.m_pushForce = 30f; hit.SetAttacker((Character)(object)player); GameObject prefab = Effects.FindPrefab("oozebomb_projectile"); if ((Object)(object)prefab != (Object)null) { GameObject go = Object.Instantiate<GameObject>(prefab, spawn, Quaternion.LookRotation(dir)); SetupProjectile(go, player, dir * 20f, hit); } yield return (object)new WaitForSeconds(0.35f); } } private static void CastArmyOfTheDead(Player player, int level) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Effects.TryCastAnimation(player, "staff_summon", "gpower"); Effects.TryPlayAt(((Component)player).transform.position, "fx_summon_start"); ((MonoBehaviour)ClassiPlugin.Instance).StartCoroutine(DeadArmy(player, level)); DamageEnemiesAround(player, ((Component)player).transform.position, 10f, delegate(HitData hit) { hit.m_damage.m_spirit = SpectralDamage(level); hit.m_damage.m_slash = (float)SpectralDamage(level) / 2f; }, 120f, new string[2] { "fx_charred_summoned_death", "vfx_HitSparks" }); } private static IEnumerator DeadArmy(Player player, int level) { for (int i = 0; i < 4; i++) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } SummonSkeleton(player, level); yield return (object)new WaitForSeconds(0.4f); } } private static Character SpawnMinion(Player player, string prefabName, Vector3 position) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) GameObject val = Effects.FindPrefab(prefabName); if ((Object)(object)val == (Object)null) { ((Character)player).Message((MessageType)1, "The summon fails... (prefab not found)", 0, (Sprite)null); return null; } GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.LookRotation(((Component)player).transform.forward)); Character component = val2.GetComponent<Character>(); if ((Object)(object)component != (Object)null) { component.m_faction = (Faction)0; component.SetTamed(true); } MonsterAI component2 = val2.GetComponent<MonsterAI>(); if ((Object)(object)component2 != (Object)null) { component2.m_alertRange = 30f; component2.SetFollowTarget(((Component)player).gameObject); } return component; } public static void UpdateMinions(Player player) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) Minions.RemoveAll((Character m) => (Object)(object)m == (Object)null || m.IsDead()); foreach (Character minion in Minions) { if ((Object)(object)minion == (Object)null || minion.IsDead()) { continue; } MonsterAI component = ((Component)minion).GetComponent<MonsterAI>(); if ((Object)(object)component == (Object)null) { continue; } Character targetCreature = component.m_targetCreature; if ((Object)(object)targetCreature != (Object)null && !targetCreature.IsDead()) { continue; } List<Character> list = EnemiesAround(((Component)minion).transform.position, 25f); if (list.Count != 0) { Character targetCreature2 = list.OrderBy((Character e) => Vector3.Distance(((Component)e).transform.position, ((Component)minion).transform.position)).First(); component.m_targetCreature = targetCreature2; ((BaseAI)component).SetAlerted(true); } } } private static void DespawnMinion(Character minion) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)minion == (Object)null)) { Effects.TryPlayAt(((Component)minion).transform.position, 5f, "fx_charred_summoned_death", "vfx_odin_despawn"); if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)minion).gameObject); } else { Object.Destroy((Object)(object)((Component)minion).gameObject); } } } private static Vector3 AimDirection(Player player) { //IL_0025: 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_002a: 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) return ((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : ((Component)player).transform.forward; } private static Vector3 EyePosition(Player player) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) return ((Component)player).transform.position + Vector3.up * 1.6f; } private static void LaunchProjectile(Player player, string prefabName, Vector3 dir, float speed, HitData hit, params string[] fallbackNames) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_005c: 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_006a: 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) List<string> list = new List<string> { prefabName }; list.AddRange(fallbackNames); GameObject val = Effects.FindPrefab(list.ToArray()); if ((Object)(object)val == (Object)null) { ((Character)player).Message((MessageType)1, "The ability fails... (prefab not found)", 0, (Sprite)null); return; } Vector3 val2 = EyePosition(player) + dir * 0.7f; GameObject go = Object.Instantiate<GameObject>(val, val2, Quaternion.LookRotation(dir)); SetupProjectile(go, player, dir * speed, hit); } private static List<Character> EnemiesAround(Vector3 center, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (from c in Character.GetAllCharacters() where (Object)(object)c != (Object)null && !c.IsPlayer() && !c.IsTamed() && !c.IsDead() && (int)c.GetFaction() != 0 && Vector3.Distance(center, ((Component)c).transform.position) <= radius select c).ToList(); } private static int DamageEnemiesAround(Player player, Vector3 center, float radius, Action<HitData> setDamage, float pushForce, string[] perTargetVfx) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (Character item in EnemiesAround(center, radius)) { HitData val = new HitData(); setDamage(val); val.m_pushForce = pushForce; val.m_point = ((Component)item).transform.position; Vector3 val2 = ((Component)item).transform.position - center; val.m_dir = ((Vector3)(ref val2)).normalized; val.SetAttacker((Character)(object)player); item.Damage(val); if (perTargetVfx != null) { Effects.TryPlayAt(((Component)item).transform.position + Vector3.up, perTargetVfx); } num++; } return num; } private static void SetupProjectile(GameObject go, Player owner, Vector3 velocity, HitData hit) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) Projectile component = go.GetComponent<Projectile>(); if ((Object)(object)component == (Object)null) { return; } MethodInfo methodInfo = typeof(Projectile).GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.Name == "Setup"); if (methodInfo == null) { Logger.LogWarning((object)"Projectile.Setup not found"); return; } ParameterInfo[] parameters = methodInfo.GetParameters(); object[] array = new object[parameters.Length]; for (int num = 0; num < parameters.Length; num++) { Type parameterType = parameters[num].ParameterType; if (typeof(Character).IsAssignableFrom(parameterType)) { array[num] = owner; } else if (parameterType == typeof(Vector3)) { array[num] = velocity; } else if (parameterType == typeof(HitData)) { array[num] = hit; } else if (parameterType == typeof(float)) { array[num] = (parameters[num].Name.ToLowerInvariant().Contains("noise") ? 10f : 1f); } else { array[num] = (parameterType.IsValueType ? Activator.CreateInstance(parameterType) : null); } } methodInfo.Invoke(component, array); } } public static class ClassGUI { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__13_0; public static UnityAction <>9__13_1; public static UnityAction <>9__13_2; public static UnityAction <>9__14_0; public static UnityAction <>9__14_1; public static UnityAction <>9__14_2; internal void <BuildClassSelection>b__13_0() { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Mage); Rebuild(); } internal void <BuildClassSelection>b__13_1() { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Berserker); Rebuild(); } internal void <BuildClassSelection>b__13_2() { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Necromancer); Rebuild(); } internal void <BuildClassInfo>b__14_0() { OfferTrophy(Player.m_localPlayer); Rebuild(); } internal void <BuildClassInfo>b__14_1() { OfferCoins(Player.m_localPlayer); Rebuild(); } internal void <BuildClassInfo>b__14_2() { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.None); Rebuild(); } } private const int TrophyXp = 50; private const int BossTrophyXp = 500; private const int CoinsPerOffer = 10; private const int CoinsXp = 20; private static readonly HashSet<string> BossTrophyTokens = new HashSet<string> { "$item_trophy_eikthyr", "$item_trophy_theelder", "$item_trophy_bonemass", "$item_trophy_dragonqueen", "$item_trophy_goblinking", "$item_trophy_seekerqueen", "$item_trophy_fader" }; private static GameObject _panel; public static bool IsOpen => (Object)(object)_panel != (Object)null; public static void Toggle() { if (IsOpen) { Close(); } else { Open(); } } public static void Open() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { Build(localPlayer); GUIManager.BlockInput(true); } } public static void Close() { if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); _panel = null; } GUIManager.BlockInput(false); } private static void Rebuild() { if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); _panel = null; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Build(localPlayer); } } private static void Build(Player player) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown _panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 700f, 620f, false); AddLine("Temple of Classes", -45f, 28, GUIManager.Instance.ValheimOrange, 44f); if (ClassSystem.GetClass(player) == PlayerClass.None) { BuildClassSelection(); } else { BuildClassInfo(player); } Vector2 position = new Vector2(0f, 30f); object obj = <>O.<0>__Close; if (obj == null) { UnityAction val = Close; <>O.<0>__Close = val; obj = (object)val; } AddButton("Close", position, 160f, 40f, (UnityAction)obj, anchorBottom: true); } private static void BuildClassSelection() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown AddLine("The gods await your decision, viking.", -85f, 15, Color.white); AddLine("The Way of the Mage", -125f, 19, GUIManager.Instance.ValheimOrange); AddLine("Master of the elements: fire, frost and lightning obey your will.", -153f, 14, Color.white); Vector2 position = new Vector2(0f, -193f); object obj = <>c.<>9__13_0; if (obj == null) { UnityAction val = delegate { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Mage); Rebuild(); }; <>c.<>9__13_0 = val; obj = (object)val; } AddButton("Become a Mage", position, 240f, 44f, (UnityAction)obj); AddLine("The Way of the Berserker", -250f, 19, GUIManager.Instance.ValheimOrange); AddLine("Fury and steel: charges, whirlwinds and slams that shake the earth.", -278f, 14, Color.white); Vector2 position2 = new Vector2(0f, -318f); object obj2 = <>c.<>9__13_1; if (obj2 == null) { UnityAction val2 = delegate { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Berserker); Rebuild(); }; <>c.<>9__13_1 = val2; obj2 = (object)val2; } AddButton("Become a Berserker", position2, 240f, 44f, (UnityAction)obj2); AddLine("The Way of the Necromancer", -375f, 19, GUIManager.Instance.ValheimOrange); AddLine("Lord of the dead: poisons, life drains and armies of skeletons.", -403f, 14, Color.white); Vector2 position3 = new Vector2(0f, -443f); object obj3 = <>c.<>9__13_2; if (obj3 == null) { UnityAction val3 = delegate { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.Necromancer); Rebuild(); }; <>c.<>9__13_2 = val3; obj3 = (object)val3; } AddButton("Become a Necromancer", position3, 240f, 44f, (UnityAction)obj3); AddLine("8 abilities to unlock, one every 10 levels, up to level 80.", -505f, 14, new Color(0.8f, 0.8f, 0.8f)); } private static void BuildClassInfo(Player player) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Expected O, but got Unknown //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Expected O, but got Unknown PlayerClass playerClass = ClassSystem.GetClass(player); int level = ClassSystem.GetLevel(player); int xp = ClassSystem.GetXp(player); string arg = ((level >= 80) ? "MAX LEVEL" : $"{xp} / {ClassSystem.XpThreshold(level + 1)} XP"); AddLine($"Way of the {playerClass} — Level {level} — {arg}", -85f, 18, Color.white); Color val = default(Color); ((Color)(ref val))..ctor(0.65f, 0.9f, 0.65f); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.6f, 0.6f, 0.6f); float num = -125f; SpellDef[] spells = Abilities.GetSpells(playerClass); foreach (SpellDef spellDef in spells) { bool flag = level >= spellDef.UnlockLevel; string text = (flag ? (spellDef.Name + ": " + spellDef.Describe(level)) : $"[Lv. {spellDef.UnlockLevel}] {spellDef.Name}: {spellDef.Describe(spellDef.UnlockLevel)}"); AddLine(text, num, 14, flag ? val : val2); num -= 25f; } AddLine("Cast abilities with " + ClassiPlugin.GetSpellKeyLabel(0) + " ... " + ClassiPlugin.GetSpellKeyLabel(7) + " (configurable)", -345f, 14, new Color(0.8f, 0.8f, 0.8f)); AddLine("Make an offering to the gods to gain experience:", -385f, 16, GUIManager.Instance.ValheimOrange); string text2 = $"Offer 1 trophy (+{50} XP)"; Vector2 position = new Vector2(-170f, -430f); object obj = <>c.<>9__14_0; if (obj == null) { UnityAction val3 = delegate { OfferTrophy(Player.m_localPlayer); Rebuild(); }; <>c.<>9__14_0 = val3; obj = (object)val3; } AddButton(text2, position, 300f, 42f, (UnityAction)obj); string text3 = $"Offer {10} coins (+{20} XP)"; Vector2 position2 = new Vector2(170f, -430f); object obj2 = <>c.<>9__14_1; if (obj2 == null) { UnityAction val4 = delegate { OfferCoins(Player.m_localPlayer); Rebuild(); }; <>c.<>9__14_1 = val4; obj2 = (object)val4; } AddButton(text3, position2, 300f, 42f, (UnityAction)obj2); Vector2 position3 = new Vector2(0f, -490f); object obj3 = <>c.<>9__14_2; if (obj3 == null) { UnityAction val5 = delegate { ClassSystem.SetClass(Player.m_localPlayer, PlayerClass.None); Rebuild(); }; <>c.<>9__14_2 = val5; obj3 = (object)val5; } AddButton("Abandon the way (resets progress)", position3, 360f, 40f, (UnityAction)obj3); } private static void OfferTrophy(Player player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)player).GetInventory(); ItemData val = null; foreach (ItemData allItem in inventory.GetAllItems()) { if ((int)allItem.m_shared.m_itemType == 13) { val = allItem; break; } } if (val == null) { ((Character)player).Message((MessageType)2, "You have no trophies to offer", 0, (Sprite)null); return; } int amount = (BossTrophyTokens.Contains(val.m_shared.m_name) ? 500 : 50); string text = Localization.instance.Localize(val.m_shared.m_name); inventory.RemoveOneItem(val); Effects.TryPlayAt(((Component)player).transform.position, "vfx_offering"); Effects.TryPlayAt(((Component)player).transform.position, "sfx_offering"); ((Character)player).Message((MessageType)2, "The gods accept " + text, 0, (Sprite)null); ClassSystem.AddXp(player, amount); } private static void OfferCoins(Player player) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory.CountItems("$item_coins", -1, true) < 10) { ((Character)player).Message((MessageType)2, $"You need at least {10} coins", 0, (Sprite)null); return; } inventory.RemoveItem("$item_coins", 10, -1, true); Effects.TryPlayAt(((Component)player).transform.position, "vfx_offering"); Effects.TryPlayAt(((Component)player).transform.position, "sfx_offering"); ClassSystem.AddXp(player, 20); } private static void AddLine(string text, float y, int fontSize, Color color, float height = 30f) { //IL_001b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) GameObject val = GUIManager.Instance.CreateText(text, _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, y), GUIManager.Instance.AveriaSerifBold, fontSize, color, true, Color.black, 640f, height, false); Text component = val.GetComponent<Text>(); if ((Object)(object)component != (Object)null) { component.alignment = (TextAnchor)4; } } private static void AddButton(string text, Vector2 position, float width, float height, UnityAction onClick, bool anchorBottom = false) { //IL_0020: 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_0025: 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_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) Vector2 val = (anchorBottom ? new Vector2(0.5f, 0f) : new Vector2(0.5f, 1f)); GameObject val2 = GUIManager.Instance.CreateButton(text, _panel.transform, val, val, position, width, height); ((UnityEvent)val2.GetComponent<Button>().onClick).AddListener(onClick); } } public enum PlayerClass { None, Mage, Berserker, Necromancer } public static class ClassSystem { private const string KeyClass = "cdv_classe"; private const string KeyXp = "cdv_xp"; public const int MaxLevel = 80; public static PlayerClass GetClass(Player player) { if ((Object)(object)player == (Object)null || player.m_customData == null || !player.m_customData.TryGetValue("cdv_classe", out var value)) { return PlayerClass.None; } if (Enum.TryParse<PlayerClass>(value, out var result)) { return result; } string text = value; string text2 = text; if (!(text2 == "Mago")) { if (text2 == "Necromante") { return PlayerClass.Necromancer; } return PlayerClass.None; } return PlayerClass.Mage; } public static void SetClass(Player player, PlayerClass cls) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) player.m_customData["cdv_classe"] = cls.ToString(); player.m_customData["cdv_xp"] = "0"; PassiveEffects.RemoveAll(player); PassiveEffects.EnsureApplied(player); if (cls != PlayerClass.None) { ((Character)player).Message((MessageType)2, $"You have chosen the way of the {cls}!", 0, (Sprite)null); Effects.TryPlayAt(((Component)player).transform.position, "vfx_odin_despawn"); } } public static int GetXp(Player player) { if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue("cdv_xp", out var value) && int.TryParse(value, out var result)) { return result; } return 0; } public static int XpThreshold(int level) { return 30 * (level - 1) + 15 * (level - 1) * level / 2; } public static int GetLevel(Player player) { int xp = GetXp(player); int i; for (i = 1; i < 80 && xp >= XpThreshold(i + 1); i++) { } return i; } public static void AddXp(Player player, int amount) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || amount <= 0 || GetClass(player) == PlayerClass.None) { return; } int level = GetLevel(player); int num = GetXp(player) + amount; player.m_customData["cdv_xp"] = num.ToString(); ((Character)player).Message((MessageType)1, $"+{amount} class XP", 0, (Sprite)null); int level2 = GetLevel(player); if (level2 <= level) { return; } ((Character)player).Message((MessageType)2, $"Class level {level2}!", 0, (Sprite)null); Effects.TryPlayAt(((Component)player).transform.position, "vfx_odin_despawn"); for (int i = level + 1; i <= level2; i++) { foreach (string item in Abilities.GetUnlockedAt(GetClass(player), i)) { ((Character)player).Message((MessageType)2, "New ability unlocked: " + item + "!", 0, (Sprite)null); } } } } public static class Effects { private static bool _triggersDumped; public static GameObject FindPrefab(params string[] names) { if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } foreach (string text in names) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if ((Object)(object)prefab != (Object)null) { return prefab; } } Logger.LogWarning((object)("No prefab found among: " + string.Join(", ", names))); return null; } public static void TryPlayAt(Vector3 position, params string[] names) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) TryPlayAt(position, 30f, names); } public static void TryPlayAt(Vector3 position, float maxLifetime, params string[] names) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) GameObject val = FindPrefab(names); if (!((Object)(object)val == (Object)null)) { GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity); if (maxLifetime > 0f) { Object.Destroy((Object)(object)val2, maxLifetime); } } } public static void TryCastAnimation(Player player, params string[] triggerNames) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 Animator animator = ((Character)player).m_animator; ZSyncAnimation zanim = ((Character)player).m_zanim; if ((Object)(object)animator == (Object)null || (Object)(object)zanim == (Object)null) { return; } foreach (string text in triggerNames) { AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { if ((int)val.type == 9 && val.name == text) { zanim.SetTrigger(text); return; } } } Logger.LogWarning((object)("No animation trigger found among: " + string.Join(", ", triggerNames))); } public static void DumpAnimatorTriggers(Player player) { if (!_triggersDumped && !((Object)(object)player == (Object)null) && !((Object)(object)((Character)player).m_animator == (Object)null)) { _triggersDumped = true; IOrderedEnumerable<string> values = from p in ((Character)player).m_animator.parameters where (int)p.type == 9 select p.name into n orderby n select n; Logger.LogInfo((object)("Player animation triggers: " + string.Join(", ", values))); } } } public static class HudOverlay { private const float SlotSize = 52f; private const float SlotGap = 6f; private const float BottomMargin = 60f; private static GUIStyle _slotStyle; private static GUIStyle _headerStyle; private static GUIStyle _keyStyle; private static GUIStyle _cooldownStyle; private static GUIStyle _lockedStyle; private static Texture2D _slotBg; private static Texture2D _overlayTex; private static readonly Dictionary<string, Sprite> IconCache = new Dictionary<string, Sprite>(); public static void Draw() { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)Hud.instance == (Object)null || Hud.instance.m_userHidden) { return; } PlayerClass playerClass = ClassSystem.GetClass(localPlayer); if (playerClass == PlayerClass.None) { return; } EnsureStyles(); SpellDef[] spells = Abilities.GetSpells(playerClass); if (spells.Length == 0) { return; } float num = (float)spells.Length * 52f + (float)(spells.Length - 1) * 6f; float num2 = ((float)Screen.width - num) / 2f; float num3 = (float)Screen.height - 60f - 52f; DrawHeader(localPlayer, num2, num3 - 44f, num); string text = null; Rect val = default(Rect); Rect rect = default(Rect); Rect val2 = default(Rect); for (int i = 0; i < spells.Length; i++) { SpellDef spellDef = spells[i]; ((Rect)(ref val))..ctor(num2 + (float)i * 58f, num3, 52f, 52f); bool flag = Abilities.IsUnlocked(localPlayer, spellDef); GUI.DrawTexture(val, (Texture)(object)_slotBg); Sprite icon = GetIcon(spellDef.IconItem); if ((Object)(object)icon != (Object)null) { ((Rect)(ref rect))..ctor(((Rect)(ref val)).x + 4f, ((Rect)(ref val)).y + 4f, ((Rect)(ref val)).width - 8f, ((Rect)(ref val)).height - 8f); Color color = GUI.color; GUI.color = (Color)(flag ? Color.white : new Color(1f, 1f, 1f, 0.25f)); DrawSprite(rect, icon); GUI.color = color; } if (!flag) { GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + ((Rect)(ref val)).height - 20f, ((Rect)(ref val)).width, 18f), $"lv{spellDef.UnlockLevel}", _lockedStyle); } else { float cooldownRemaining = Abilities.GetCooldownRemaining(spellDef.Name); if (cooldownRemaining > 0f) { float num4 = Mathf.Clamp01(cooldownRemaining / spellDef.Cooldown); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x, ((Rect)(ref val)).y + ((Rect)(ref val)).height * (1f - num4), ((Rect)(ref val)).width, ((Rect)(ref val)).height * num4); GUI.DrawTexture(val2, (Texture)(object)_overlayTex); GUI.Label(val, $"{cooldownRemaining:0}", _cooldownStyle); } } GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y - 16f, ((Rect)(ref val)).width, 16f), ClassiPlugin.GetSpellKeyLabel(i), _keyStyle); if (((Rect)(ref val)).Contains(Event.current.mousePosition)) { text = (flag ? (spellDef.Name + ": " + spellDef.Describe(ClassSystem.GetLevel(localPlayer))) : $"{spellDef.Name} (unlocks at level {spellDef.UnlockLevel})"); } } if (text != null) { GUI.Label(new Rect(num2, num3 - 66f, num, 20f), text, _headerStyle); } } private static void DrawHeader(Player player, float x, float y, float width) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) int level = ClassSystem.GetLevel(player); int xp = ClassSystem.GetXp(player); string arg = ((level >= 80) ? "MAX" : $"{xp}/{ClassSystem.XpThreshold(level + 1)}"); string text = $"<b>{ClassSystem.GetClass(player)}</b> Lv. {level} XP {arg}"; if (Abilities.DebugUnlockAll) { text += " <color=#ffcc00>[DEBUG]</color>"; } GUI.Label(new Rect(x, y, width, 20f), text, _headerStyle); } private static Sprite GetIcon(string itemName) { if (string.IsNullOrEmpty(itemName) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } if (IconCache.TryGetValue(itemName, out var value)) { return value; } Sprite val = null; try { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemName); ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { val = val2.m_itemData.GetIcon(); } } catch { } IconCache[itemName] = val; return val; } private static void DrawSprite(Rect rect, Sprite sprite) { //IL_005e: 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_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Texture2D texture = sprite.texture; try { Rect textureRect = sprite.textureRect; GUI.DrawTextureWithTexCoords(rect, (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height)); } catch { GUI.DrawTexture(rect, (Texture)(object)texture, (ScaleMode)2); } } private static void EnsureStyles() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009a: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00ed: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_0125: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (_slotStyle == null) { _slotBg = MakeTexture(new Color(0f, 0f, 0f, 0.6f)); _overlayTex = MakeTexture(new Color(0f, 0f, 0f, 0.7f)); _slotStyle = new GUIStyle(GUI.skin.box); _headerStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, richText = true, alignment = (TextAnchor)4 }; _headerStyle.normal.textColor = Color.white; _keyStyle = new GUIStyle(GUI.skin.label) { fontSize = 11, alignment = (TextAnchor)4 }; _keyStyle.normal.textColor = new Color(0.85f, 0.85f, 0.85f); _cooldownStyle = new GUIStyle(GUI.skin.label) { fontSize = 20, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; _cooldownStyle.normal.textColor = Color.white; _lockedStyle = new GUIStyle(GUI.skin.label) { fontSize = 11, alignment = (TextAnchor)4 }; _lockedStyle.normal.textColor = new Color(0.7f, 0.7f, 0.7f); } } private static Texture2D MakeTexture(Color color) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } } public static class Localizations { public static void Register() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "Italian"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "piece_cdv_tempio", "Tempio delle Classi" }, { "piece_cdv_tempio_desc", "Un altare sacro dove scegliere la propria via e offrire sacrifici agli dèi." }, { "piece_cdv_tempio_use", "Prega" } }); text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "piece_cdv_tempio", "Temple of Classes" }, { "piece_cdv_tempio_desc", "A sacred altar where you choose your path and offer sacrifices to the gods." }, { "piece_cdv_tempio_use", "Pray" } }); } } public static class PassiveEffects { public const string MageName = "SE_CDV_Mago"; public const string BerserkerName = "SE_CDV_Berserker"; public const string NecromancerName = "SE_CDV_Necromante"; public const string RuneShieldName = "SE_CDV_Scudo"; public const string FuryName = "SE_CDV_Furia"; public const string IronSkinName = "SE_CDV_Ferro"; public const string BoneArmorName = "SE_CDV_Ossa"; private static readonly Dictionary<PlayerClass, string> PassiveByClass = new Dictionary<PlayerClass, string> { { PlayerClass.Mage, "SE_CDV_Mago" }, { PlayerClass.Berserker, "SE_CDV_Berserker" }, { PlayerClass.Necromancer, "SE_CDV_Necromante" } }; private static readonly Dictionary<string, string> IconItemByEffect = new Dictionary<string, string> { { "SE_CDV_Mago", "SurtlingCore" }, { "SE_CDV_Scudo", "SurtlingCore" }, { "SE_CDV_Berserker", "TrophyWolf" }, { "SE_CDV_Furia", "TrophyWolf" }, { "SE_CDV_Ferro", "ArmorIronChest" }, { "SE_CDV_Necromante", "TrophySkeleton" }, { "SE_CDV_Ossa", "BoneFragments" } }; private static readonly Dictionary<string, StatusEffect> Registered = new Dictionary<string, StatusEffect>(); public static void Register() { Create<SE_MagePassive>("SE_CDV_Mago", "Way of the Mage", "Elemental damage and stamina/eitr regeneration increased for every class level."); Create<SE_BerserkerPassive>("SE_CDV_Berserker", "Way of the Berserker", "Melee damage increased, cheaper attacks and more carry weight for every class level."); Create<SE_NecromancerPassive>("SE_CDV_Necromante", "Way of the Necromancer", "Poison and spirit damage increased, regeneration from beyond the grave for every class level."); Create<SE_RuneShield>("SE_CDV_Scudo", "Rune Shield", "A barrier of runes hardens your defense.", 20f); Create<SE_Fury>("SE_CDV_Furia", "Berserker Fury", "Increased damage and attacks that barely consume stamina.", 15f); Create<SE_IronSkin>("SE_CDV_Ferro", "Iron Skin", "Your skin is hard as iron.", 20f); Create<SE_BoneArmor>("SE_CDV_Ossa", "Bone Armor", "Ancient bones protect you.", 20f); } private static void Create<T>(string name, string displayName, string tooltip, float ttl = 0f) where T : StatusEffect { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown T val = ScriptableObject.CreateInstance<T>(); ((Object)(object)val).name = name; ((StatusEffect)val).m_name = displayName; ((StatusEffect)val).m_tooltip = tooltip; ((StatusEffect)val).m_ttl = ttl; ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)val, false)); Registered[name] = (StatusEffect)(object)val; } public static void EnsureApplied(Player player) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null) { return; } PlayerClass playerClass = ClassSystem.GetClass(player); foreach (KeyValuePair<PlayerClass, string> item in PassiveByClass) { int stableHashCode = StringExtensionMethods.GetStableHashCode(item.Value); if (item.Key == playerClass) { if (!sEMan.HaveStatusEffect(stableHashCode)) { AssignIcon(item.Value); sEMan.AddStatusEffect(stableHashCode, false, 0, 0f); } } else if (sEMan.HaveStatusEffect(stableHashCode)) { sEMan.RemoveStatusEffect(stableHashCode, true); } } } public static void RemoveAll(Player player) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null) { return; } foreach (string key in Registered.Keys) { sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode(key), true); } } public static void ApplyTimedEffect(Player player, string name) { AssignIcon(name); ((Character)player).GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode(name), true, 0, 0f); } private static void AssignIcon(string effectName) { if (!Registered.TryGetValue(effectName, out var value) || (Object)(object)value.m_icon != (Object)null || (Object)(object)ObjectDB.instance == (Object)null || !IconItemByEffect.TryGetValue(effectName, out var value2)) { return; } try { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(value2); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val != (Object)null) { value.m_icon = val.m_itemData.GetIcon(); } } catch { } } } public abstract class SE_ClassBase : StatusEffect { protected static int Lvl { get { Player localPlayer = Player.m_localPlayer; return (!((Object)(object)localPlayer != (Object)null)) ? 1 : ClassSystem.GetLevel(localPlayer); } } protected static bool IsMeleeSkill(SkillType skill) { //IL_0001: 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) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected I4, but got Unknown switch (skill - 1) { case 0: case 1: case 2: case 3: case 4: case 6: case 10: return true; default: return false; } } } public class SE_MagePassive : SE_ClassBase { public override void ModifyAttack(SkillType skill, ref HitData hitData) { float num = 1f + 0.01f * (float)SE_ClassBase.Lvl; hitData.m_damage.m_fire *= num; hitData.m_damage.m_frost *= num; hitData.m_damage.m_lightning *= num; hitData.m_damage.m_poison *= num; hitData.m_damage.m_spirit *= num; } public override void ModifyStaminaRegen(ref float staminaRegen) { staminaRegen *= 1f + 0.005f * (float)SE_ClassBase.Lvl; } public override void ModifyEitrRegen(ref float eitrRegen) { eitrRegen *= 1f + 0.015f * (float)SE_ClassBase.Lvl; } } public class SE_BerserkerPassive : SE_ClassBase { public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (SE_ClassBase.IsMeleeSkill(skill)) { hitData.ApplyModifier(1f + 0.01f * (float)SE_ClassBase.Lvl); } } public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= Mathf.Max(0.5f, 1f - 0.005f * (float)SE_ClassBase.Lvl); } public override void ModifyMaxCarryWeight(float baseLimit, ref float limit) { limit += 1.5f * (float)SE_ClassBase.Lvl; } } public class SE_NecromancerPassive : SE_ClassBase { public override void ModifyAttack(SkillType skill, ref HitData hitData) { float num = 1f + 0.015f * (float)SE_ClassBase.Lvl; hitData.m_damage.m_poison *= num; hitData.m_damage.m_spirit *= num; } public override void ModifyHealthRegen(ref float regenMultiplier) { regenMultiplier *= 1f + 0.005f * (float)SE_ClassBase.Lvl; } public override void ModifyEitrRegen(ref float eitrRegen) { eitrRegen *= 1f + 0.01f * (float)SE_ClassBase.Lvl; } } public class SE_RuneShield : SE_ClassBase { public override void ModifyArmorMods(ref float armorMods) { armorMods += 100f + 2f * (float)SE_ClassBase.Lvl; } } public class SE_Fury : SE_ClassBase { public override void ModifyAttack(SkillType skill, ref HitData hitData) { hitData.ApplyModifier(1.4f); } public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.2f; } } public class SE_IronSkin : SE_ClassBase { public override void ModifyArmorMods(ref float armorMods) { armorMods += 80f + 2f * (float)SE_ClassBase.Lvl; } } public class SE_BoneArmor : SE_ClassBase { public override void ModifyArmorMods(ref float armorMods) { armorMods += 70f + 2f * (float)SE_ClassBase.Lvl; } } [BepInPlugin("gianl.waysofthegods", "WaysOfTheGods", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class ClassiPlugin : BaseUnityPlugin { public const string PluginGuid = "gianl.waysofthegods"; public const string PluginName = "WaysOfTheGods"; public const string PluginVersion = "1.0.1"; public static ClassiPlugin Instance; public static ConfigEntry<KeyboardShortcut>[] SpellKeys; public static ConfigEntry<KeyCode> KeyDebugUnlock; public static ConfigEntry<float> XpMultiplier; private Harmony _harmony; private float _nextPassiveCheck; private void Awake() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown Instance = this; SpellKeys = new ConfigEntry<KeyboardShortcut>[8]; for (int i = 0; i < SpellKeys.Length; i++) { SpellKeys[i] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", $"Ability{i + 1}", new KeyboardShortcut((KeyCode)(49 + i), (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), $"Cast class ability {i + 1}"); } KeyDebugUnlock = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Debug", "UnlockAllAbilities", (KeyCode)290, "Test key: toggles temporary unlock of all abilities (does not touch XP)"); XpMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Experience", "XpMultiplier", 1f, "Multiplier for XP gained from kills"); Localizations.Register(); PassiveEffects.Register(); Temple.Register(); _harmony = new Harmony("gianl.waysofthegods"); XpPatches.Apply(_harmony); Logger.LogInfo((object)"WaysOfTheGods loaded: build the Temple of Classes to get started!"); } private void Update() { //IL_0093: 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_00e2: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (ClassGUI.IsOpen && Input.GetKeyDown((KeyCode)27)) { ClassGUI.Close(); return; } if (Time.time > _nextPassiveCheck) { _nextPassiveCheck = Time.time + 1f; PassiveEffects.EnsureApplied(localPlayer); Effects.DumpAnimatorTriggers(localPlayer); Abilities.UpdateMinions(localPlayer); } if (ClassSystem.GetClass(localPlayer) == PlayerClass.None || IsAnyUiOpen()) { return; } if (Input.GetKeyDown(KeyDebugUnlock.Value)) { Abilities.DebugUnlockAll = !Abilities.DebugUnlockAll; ((Character)localPlayer).Message((MessageType)2, Abilities.DebugUnlockAll ? "DEBUG: all abilities unlocked" : "DEBUG: ability unlock disabled", 0, (Sprite)null); } for (int i = 0; i < SpellKeys.Length; i++) { KeyboardShortcut value = SpellKeys[i].Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Abilities.CastSpell(localPlayer, i); break; } } } public static string GetSpellKeyLabel(int index) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (SpellKeys == null || index < 0 || index >= SpellKeys.Length) { return string.Empty; } KeyboardShortcut value = SpellKeys[index].Value; List<string> list = new List<string>(); foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { list.Add(ShortKeyName(modifier)); } list.Add(ShortKeyName(((KeyboardShortcut)(ref value)).MainKey)); return string.Join("+", list); } private unsafe static string ShortKeyName(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0025: 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_0028: 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_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_004f: Expected I4, but got Unknown //IL_0016: 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_001b: Expected I4, but got Unknown if ((int)key >= 48 && (int)key <= 57) { return (key - 48).ToString(); } KeyCode val = key; KeyCode val2 = val; switch (val2 - 303) { case 0: case 1: return "Shift"; case 2: case 3: return "Ctrl"; case 4: case 5: return "Alt"; default: return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } private static bool IsAnyUiOpen() { try { return ClassGUI.IsOpen || Console.IsVisible() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Menu.IsVisible() || InventoryGui.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen(); } catch { return false; } } private void OnGUI() { HudOverlay.Draw(); } } public class RuneDome : MonoBehaviour { public Player Owner; public float Radius = 8f; public float EndTime; private float _nextTick; private bool _armorApplied; private void Update() { if (Time.time > EndTime) { RemoveArmor(); Object.Destroy((Object)(object)((Component)this).gameObject); } else if (!(Time.time < _nextTick)) { _nextTick = Time.time + 0.25f; UpdateArmor(); DissolveEnemyProjectiles(); RepelEnemies(); } } private void UpdateArmor() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { SEMan sEMan = ((Character)localPlayer).GetSEMan(); int stableHashCode = StringExtensionMethods.GetStableHashCode("SE_CDV_Scudo"); if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) <= Radius) { sEMan.AddStatusEffect(stableHashCode, true, 0, 0f); _armorApplied = true; } else if (_armorApplied && sEMan.HaveStatusEffect(stableHashCode)) { sEMan.RemoveStatusEffect(stableHashCode, true); _armorApplied = false; } } } private void DissolveEnemyProjectiles() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) Projectile[] array = Object.FindObjectsByType<Projectile>((FindObjectsSortMode)0); foreach (Projectile val in array) { if (!((Object)(object)val == (Object)null) && !(Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) > Radius)) { Character owner = val.m_owner; if (!((Object)(object)owner != (Object)null) || !owner.IsPlayer()) { Effects.TryPlayAt(((Component)val).transform.position, 2f, "fx_StaffShield_Hit"); Object.Destroy((Object)(object)((Component)val).gameObject); } } } } private void RepelEnemies() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00d5: 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_00e2: 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) foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer() && !allCharacter.IsTamed() && !allCharacter.IsDead() && !(Vector3.Distance(((Component)allCharacter).transform.position, ((Component)this).transform.position) > Radius)) { Vector3 dir = ((Component)allCharacter).transform.position - ((Component)this).transform.position; dir.y = 0f; dir = ((((Vector3)(ref dir)).sqrMagnitude > 0.01f) ? ((Vector3)(ref dir)).normalized : ((Component)this).transform.forward); HitData val = new HitData(); val.m_pushForce = 80f; val.m_dir = dir; val.m_point = ((Component)allCharacter).transform.position; val.SetAttacker((Character)(object)Owner); allCharacter.Damage(val); } } } private void RemoveArmor() { if (_armorApplied) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).GetSEMan().RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_CDV_Scudo"), true); } _armorApplied = false; } } private void OnDestroy() { RemoveArmor(); } } public static class Temple { public const string PieceName = "piece_cdv_tempio"; public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += CreatePiece; } private static void CreatePiece() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown PieceConfig val = new PieceConfig(); val.Name = "$piece_cdv_tempio"; val.Description = "$piece_cdv_tempio_desc"; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Misc; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("Stone", 20, 0, true), new RequirementConfig("FineWood", 10, 0, true), new RequirementConfig("SurtlingCore", 3, 0, true) }; PieceConfig val2 = val; CustomPiece val3 = new CustomPiece("piece_cdv_tempio", "guard_stone", val2); GameObject piecePrefab = val3.PiecePrefab; PrivateArea component = piecePrefab.GetComponent<PrivateArea>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } piecePrefab.AddComponent<TempleInteract>(); BuildTempleVisual(piecePrefab); PieceManager.Instance.AddPiece(val3); PrefabManager.OnVanillaPrefabsAvailable -= CreatePiece; } private static void BuildTempleVisual(GameObject prefab) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or