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 Norns v2.0.0
plugins/Norns/Norns.dll
Decompiled a month 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.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [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("Norns")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+22c6aac6b0f3f6f1500297b9af449f8e05818f33")] [assembly: AssemblyProduct("Norns")] [assembly: AssemblyTitle("Norns")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Norns { public sealed class ArcLightningVfxController : MonoBehaviour { private const int PointCount = 19; private const float RevealDuration = 0.065f; private const float HoldDuration = 0.145f; private const float FadeDuration = 0.16f; private const float RepathInterval = 0.032f; public LineRenderer OuterGlow; public LineRenderer MainChannel; public LineRenderer WhiteCore; public LineRenderer[] Branches; public Transform SourceGroup; public Transform TargetGroup; public Transform ResidualGroup; public Light ImpactLight; private readonly Vector3[] _points = (Vector3[])(object)new Vector3[19]; private Vector3[][] _branchPoints; private ParticleSystem[] _sourceParticles; private ParticleSystem[] _targetParticles; private ParticleSystem[] _residualParticles; private Vector3 _from; private Vector3 _to; private Vector3 _direction; private Vector3 _side; private Vector3 _up; private float _length; private float _delay; private float _startedAt; private float _nextRepathAt; private int _seed; private int _repath; private bool _initialized; private bool _sourcePlayed; private bool _impactPlayed; private void OnEnable() { _sourceParticles = ParticlesUnder(SourceGroup); _targetParticles = ParticlesUnder(TargetGroup); _residualParticles = ParticlesUnder(ResidualGroup); StopAndClear(_sourceParticles); StopAndClear(_targetParticles); StopAndClear(_residualParticles); SetLineVisible(OuterGlow, visible: false); SetLineVisible(MainChannel, visible: false); SetLineVisible(WhiteCore, visible: false); if (Branches != null) { LineRenderer[] branches = Branches; for (int i = 0; i < branches.Length; i++) { SetLineVisible(branches[i], visible: false); } } if ((Object)(object)ImpactLight != (Object)null) { ImpactLight.intensity = 0f; } _startedAt = Time.time; _initialized = false; _sourcePlayed = false; _impactPlayed = false; } public unsafe void Initialize(Vector3 from, Vector3 to, float delay, int chainIndex) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) _from = from; _to = to; Vector3 val = to - from; _length = ((Vector3)(ref val)).magnitude; if (_length < 0.05f) { val = Vector3.forward * 0.05f; } _direction = ((Vector3)(ref val)).normalized; Vector3 val2 = Vector3.Cross(_direction, Vector3.up); _side = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref _side)).sqrMagnitude < 0.01f) { val2 = Vector3.Cross(_direction, Vector3.right); _side = ((Vector3)(ref val2)).normalized; } val2 = Vector3.Cross(_side, _direction); _up = ((Vector3)(ref val2)).normalized; _delay = Mathf.Max(0f, delay); _seed = ((object)(*(Vector3*)(&from))/*cast due to .constrained prefix*/).GetHashCode() ^ (((object)(*(Vector3*)(&to))/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ (chainIndex * 7919); _repath = 0; _nextRepathAt = 0f; _startedAt = Time.time; _initialized = true; _sourcePlayed = false; _impactPlayed = false; if ((Object)(object)SourceGroup != (Object)null) { SourceGroup.position = from; } if ((Object)(object)TargetGroup != (Object)null) { TargetGroup.position = to; } if ((Object)(object)ResidualGroup != (Object)null) { ResidualGroup.position = to; } if ((Object)(object)ImpactLight != (Object)null) { ((Component)ImpactLight).transform.position = to; } int num = ((Branches != null) ? Branches.Length : 0); _branchPoints = new Vector3[num][]; for (int i = 0; i < num; i++) { _branchPoints[i] = (Vector3[])(object)new Vector3[4]; } } private void Update() { if (!_initialized) { if (Time.time - _startedAt > 0.25f) { Object.Destroy((Object)(object)((Component)this).gameObject); } return; } float num = Time.time - _startedAt - _delay; if (!(num < 0f)) { float num2 = 0.21f; float num3 = num2 + 0.16f; if (!_sourcePlayed) { _sourcePlayed = true; Play(_sourceParticles); } if (num <= num2 && num >= _nextRepathAt) { RebuildPath(num); _nextRepathAt = num + 0.032f; } float reveal = Smooth01(num / 0.065f); float num4 = ((num <= num2) ? 1f : (1f - Smooth01((num - num2) / 0.16f))); float strobe = 0.88f + Mathf.Sin(num * 91f + (float)_seed * 0.001f) * 0.08f + Mathf.Sin(num * 143f + 1.7f) * 0.04f; DrawMainLines(reveal, num4, strobe); DrawBranches(reveal, num4); if (!_impactPlayed && num >= 0.053299997f) { PlayImpact(); } if ((Object)(object)ImpactLight != (Object)null) { float num5 = Mathf.Max(0f, num - 0.053299997f); float num6 = Mathf.Exp((0f - num5) * 18f) * 4.6f; float num7 = Mathf.Clamp01(1f - num5 / 0.24f) * 0.65f; ImpactLight.intensity = (_impactPlayed ? ((num6 + num7) * num4) : 0f); } if (num >= num3 + 0.34f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private void RebuildPath(float localTime) { //IL_00dc: 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_00e8: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: 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_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) _repath++; float num = Mathf.Clamp(_length * 0.075f, 0.18f, 0.86f); for (int i = 0; i < 19; i++) { float num2 = (float)i / 18f; float num3 = Mathf.Sin(num2 * (float)Math.PI); float num4 = Mathf.Sin(num2 * 16.2f + (float)_seed * 0.00031f + (float)_repath * 1.73f); float num5 = Mathf.Sin(num2 * 39.7f - (float)_seed * 0.00019f - (float)_repath * 2.31f); float num6 = Mathf.Sin(num2 * 27.1f + (float)_seed * 0.00047f + (float)_repath * 1.19f); float num7 = num4 * 0.68f + num5 * 0.32f; _points[i] = Vector3.Lerp(_from, _to, num2) + _side * num7 * num * num3 + _up * num6 * num * 0.58f * num3; } _points[0] = _from; _points[18] = _to; if (Branches != null) { for (int j = 0; j < Branches.Length; j++) { int num8 = Mathf.Clamp(3 + j * 2, 2, 16); Vector3 val = _points[num8]; float num9 = (((j & 1) == 0) ? 1f : (-1f)); float num10 = (float)_seed * 0.00023f + (float)j * 1.91f + (float)_repath * 0.74f; Vector3 val2 = _side * num9 * (0.72f + Mathf.Abs(Mathf.Sin(num10)) * 0.34f) + _up * Mathf.Sin(num10 * 1.37f) * 0.54f + _direction * (0.12f + (float)j * 0.025f); Vector3 normalized = ((Vector3)(ref val2)).normalized; float num11 = Mathf.Clamp(_length * (0.1f + (float)j * 0.008f), 0.62f, 1.65f); Vector3[] obj = _branchPoints[j]; obj[0] = val; obj[1] = val + normalized * num11 * 0.34f + _up * Mathf.Sin(num10 + 0.8f) * 0.13f; obj[2] = val + normalized * num11 * 0.69f - _side * num9 * 0.12f; obj[3] = val + normalized * num11; } } } private void DrawMainLines(float reveal, float fade, float strobe) { //IL_0037: 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_0083: Unknown result type (might be due to invalid IL or missing references) int visible = Mathf.Clamp(Mathf.CeilToInt(reveal * 18f) + 1, 2, 19); DrawLine(OuterGlow, visible, new Color(0.16f, 0.42f, 1f, 0.24f * fade * strobe)); DrawLine(MainChannel, visible, new Color(0.28f, 0.76f, 1f, 0.82f * fade * strobe)); DrawLine(WhiteCore, visible, new Color(0.93f, 0.99f, 1f, fade)); } private void DrawLine(LineRenderer line, int visible, Color color) { //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_0033: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)line == (Object)null)) { ((Renderer)line).enabled = true; line.positionCount = visible; line.startColor = color; line.endColor = color; for (int i = 0; i < visible; i++) { line.SetPosition(i, _points[i]); } } } private void DrawBranches(float reveal, float fade) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (Branches == null) { return; } float num = fade * Smooth01((reveal - 0.26f) / 0.42f); Color val2 = default(Color); for (int i = 0; i < Branches.Length; i++) { LineRenderer val = Branches[i]; if (!((Object)(object)val == (Object)null)) { float num2 = 0.62f + Mathf.Sin((Time.time - _startedAt) * 107f + (float)i * 2.1f) * 0.24f; ((Color)(ref val2))..ctor(0.38f, 0.79f, 1f, Mathf.Clamp01(num * num2 * (1f - (float)i * 0.055f))); ((Renderer)val).enabled = val2.a > 0.015f; if (((Renderer)val).enabled) { val.positionCount = 4; val.startColor = val2; val.endColor = new Color(val2.r, val2.g, val2.b, 0f); val.SetPositions(_branchPoints[i]); } } } } private void PlayImpact() { //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_0039: Unknown result type (might be due to invalid IL or missing references) _impactPlayed = true; Play(_targetParticles); Play(_residualParticles); Effects.InstantiateLocal("fx_chainlightning_hit", _to, Quaternion.identity, 4f); SpellAudio.PlayArcLightningHop(_to); } private static ParticleSystem[] ParticlesUnder(Transform root) { if (!((Object)(object)root == (Object)null)) { return ((Component)root).GetComponentsInChildren<ParticleSystem>(true); } return (ParticleSystem[])(object)new ParticleSystem[0]; } private static void Play(ParticleSystem[] systems) { foreach (ParticleSystem val in systems) { if ((Object)(object)val != (Object)null) { val.Play(true); } } } private static void StopAndClear(ParticleSystem[] systems) { foreach (ParticleSystem val in systems) { if ((Object)(object)val != (Object)null) { val.Stop(true, (ParticleSystemStopBehavior)0); } } } private static void SetLineVisible(LineRenderer line, bool visible) { if ((Object)(object)line != (Object)null) { ((Renderer)line).enabled = visible; } } private static float Smooth01(float value) { value = Mathf.Clamp01(value); return value * value * (3f - 2f * value); } } public sealed class ArcLightningChargeVfxController : MonoBehaviour { private static readonly List<ArcLightningChargeVfxController> Active = new List<ArcLightningChargeVfxController>(); public Light EffectLight; public float Lifetime = 0.88f; private ParticleSystem[] _particles; private Transform _handAnchor; private float _startedAt; private float _cancelAt = -1f; private void OnEnable() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) _particles = ((Component)this).GetComponentsInChildren<ParticleSystem>(true); _startedAt = Time.time; _cancelAt = -1f; _handAnchor = FindNearestRightHand(((Component)this).transform.position); Active.Add(this); ParticleSystem[] particles = _particles; foreach (ParticleSystem obj in particles) { obj.Stop(true, (ParticleSystemStopBehavior)0); obj.Play(true); } if ((Object)(object)EffectLight != (Object)null) { EffectLight.intensity = 0f; } } private void OnDisable() { Active.Remove(this); } private void Update() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_006a: Unknown result type (might be due to invalid IL or missing references) float num = Time.time - _startedAt; if ((Object)(object)_handAnchor != (Object)null) { Vector3 val = _handAnchor.position + _handAnchor.forward * 0.14f; ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, val, 1f - Mathf.Exp((0f - Time.deltaTime) * 28f)); } float num2 = ((_cancelAt < 0f) ? 1f : Mathf.Clamp01(1f - (Time.time - _cancelAt) / 0.12f)); if ((Object)(object)EffectLight != (Object)null) { float num3 = Smooth01(num / 0.55f); float num4 = 0.88f + Mathf.Sin(num * 49f) * 0.12f; EffectLight.intensity = num3 * num4 * 1.25f * num2; } if (_cancelAt >= 0f) { if (Time.time - _cancelAt >= 0.14f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } else if (num >= Lifetime) { Object.Destroy((Object)(object)((Component)this).gameObject); } } public void Cancel() { if (!(_cancelAt >= 0f)) { _cancelAt = Time.time; ParticleSystem[] particles = _particles; for (int i = 0; i < particles.Length; i++) { particles[i].Stop(true, (ParticleSystemStopBehavior)1); } } } public static void CancelNearest(Vector3 position, float maximumDistance = 3.5f) { //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) ArcLightningChargeVfxController arcLightningChargeVfxController = null; float num = maximumDistance; for (int num2 = Active.Count - 1; num2 >= 0; num2--) { ArcLightningChargeVfxController arcLightningChargeVfxController2 = Active[num2]; if ((Object)(object)arcLightningChargeVfxController2 == (Object)null) { Active.RemoveAt(num2); } else { float num3 = Vector3.Distance(((Component)arcLightningChargeVfxController2).transform.position, position); if (!(num3 >= num)) { num = num3; arcLightningChargeVfxController = arcLightningChargeVfxController2; } } } arcLightningChargeVfxController?.Cancel(); } private static Transform FindNearestRightHand(Vector3 position) { //IL_0028: 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) Player val = null; float num = 3.5f; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null)) { float num2 = Vector3.Distance(position, ((Component)allPlayer).transform.position); if (!(num2 >= num)) { num = num2; val = allPlayer; } } } if ((Object)(object)val == (Object)null) { return null; } Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>(); if (!((Object)(object)componentInChildren != (Object)null) || !componentInChildren.isHuman) { return null; } return componentInChildren.GetBoneTransform((HumanBodyBones)18); } private static float Smooth01(float value) { value = Mathf.Clamp01(value); return value * value * (3f - 2f * value); } } public sealed class BerserkerAuraVfxController : MonoBehaviour { public Transform FormationGroup; public Transform BodyGroup; public Transform GroundGroup; public Transform DissipationGroup; public ParticleSystem HeartbeatPulse; public Light AuraLight; public float Lifetime = 12f; public float HeartbeatInterval; public float BaseIntensity = 0.55f; private Player _player; private Transform _chest; private float _startedAt; private int _heartbeats; private bool _ending; private float _endStartedAt; private void OnEnable() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _player = BerserkerVfxSupport.FindNearestPlayer(((Component)this).transform.position); _chest = BerserkerVfxSupport.ChestAnchor(_player); _startedAt = Time.time; _heartbeats = 0; _ending = false; BerserkerVfxSupport.Play(FormationGroup); BerserkerVfxSupport.Play(BodyGroup); BerserkerVfxSupport.Play(GroundGroup); BerserkerVfxSupport.StopAndClear(DissipationGroup); if ((Object)(object)AuraLight != (Object)null) { AuraLight.intensity = 0f; } } private void LateUpdate() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_01f5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_player == (Object)null) { _player = BerserkerVfxSupport.FindNearestPlayer(((Component)this).transform.position); _chest = BerserkerVfxSupport.ChestAnchor(_player); } float num = Time.time - _startedAt; Vector3 val = (((Object)(object)_player != (Object)null) ? ((Component)_player).transform.position : ((Component)this).transform.position); Quaternion rotation = (((Object)(object)_player != (Object)null) ? ((Component)_player).transform.rotation : ((Component)this).transform.rotation); Vector3 position = (((Object)(object)_chest != (Object)null) ? _chest.position : (val + Vector3.up * 1.32f)); ((Component)this).transform.position = val; if ((Object)(object)FormationGroup != (Object)null) { FormationGroup.position = position; FormationGroup.rotation = rotation; } if ((Object)(object)BodyGroup != (Object)null) { BodyGroup.position = position; BodyGroup.rotation = rotation; } if ((Object)(object)GroundGroup != (Object)null) { GroundGroup.position = val + Vector3.up * 0.05f; GroundGroup.rotation = rotation; } if ((Object)(object)DissipationGroup != (Object)null) { DissipationGroup.position = position; DissipationGroup.rotation = rotation; } if (HeartbeatInterval > 0.05f && !_ending) { int num2 = Mathf.FloorToInt(num / HeartbeatInterval); while (_heartbeats < num2) { _heartbeats++; ParticleSystem heartbeatPulse = HeartbeatPulse; if (heartbeatPulse != null) { heartbeatPulse.Emit(18); } } } if ((Object)(object)AuraLight != (Object)null) { ((Component)AuraLight).transform.position = position; float num3 = BerserkerVfxSupport.Smooth01(num / 0.32f); float num4 = 1f - BerserkerVfxSupport.Smooth01((num - Lifetime) / 0.55f); float num5 = ((HeartbeatInterval > 0.05f) ? (1f + Mathf.Pow(1f - Mathf.Repeat(num / HeartbeatInterval, 1f), 4f) * 0.55f) : (1f + Mathf.Sin(num * 1.9f) * 0.1f)); AuraLight.intensity = num3 * num4 * BaseIntensity * num5; } if (!_ending && num >= Lifetime) { _ending = true; _endStartedAt = Time.time; BerserkerVfxSupport.StopEmitting(FormationGroup); BerserkerVfxSupport.StopEmitting(BodyGroup); BerserkerVfxSupport.StopEmitting(GroundGroup); BerserkerVfxSupport.Play(DissipationGroup); } if (_ending && Time.time - _endStartedAt >= 1.45f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public static class BerserkerClass { public const string PassiveId = "wrathbound"; public const float RendingWindow = 8f; public const float RendingDamage = 34f; public const float WarCryRadius = 8f; public const float WarCryFuryGain = 50f; private const float WarCryStagger = 10f; public const float BloodstormRadius = 5f; public const float BloodstormDamage = 28f; public const int BloodstormPulses = 3; public const float BloodstormDuration = 2.55f; public const float BloodstormInterval = 0.84999996f; public const int BloodstormSpins = 4; private const float SwingChainSettle = 0.15f; public const float BearskinDuration = 12f; public const float BearskinDamageReduction = 0.4f; public const float BearskinTauntRadius = 12f; public const float BearskinRegenPerSecond = 4f; private const float BearskinTauntInterval = 1.5f; public const float RageDuration = 12f; public const float RageLifeSteal = 0.15f; public const float RageBurstRadius = 6f; public const float RageBurstDamage = 40f; private static Player _statePlayer; private static float _rendingUntil; private static float _rendingExtraDamage; private static float _bearskinUntil; private static float _rageUntil; private static bool _rageWasActive; private static Player _animationAttackPlayer; private static float _suppressAnimationAttackUntil; public static readonly Spell[] Spells = new Spell[5] { new Spell { Id = "rending_blow", UnlockLevel = 10, Cooldown = 5f, Resource = AbilityResource.Fury, ResourceCost = 20f, CastTime = 0f, BaseDamage = 34f, CastTrigger = null, Describe = (int lvl) => Loc.F("spell_rending_blow_desc", 8f, Progression.Dmg(34f, lvl)), Cast = ArmRendingBlow }, new Spell { Id = "war_cry", UnlockLevel = 20, Cooldown = 30f, Resource = AbilityResource.Fury, ResourceCost = 0f, CastTime = 0f, BaseDamage = 0f, CastEmote = "roar", CastTrigger = "gpower", Describe = (int _) => Loc.F("spell_war_cry_desc", 8f, 50f), Cast = CastWarCry }, new Spell { Id = "bloodstorm", UnlockLevel = 30, Cooldown = 18f, Resource = AbilityResource.Fury, ResourceCost = 45f, CastTime = 0f, BaseDamage = 28f, CastTrigger = null, Describe = (int lvl) => Loc.F("spell_bloodstorm_desc", Progression.Dmg(28f, lvl), 5f), Cast = CastBloodstorm }, new Spell { Id = "bearskin", IconStem = "deathless", UnlockLevel = 40, Cooldown = 60f, Resource = AbilityResource.Fury, ResourceCost = 55f, CastTime = 0f, BaseDamage = 0f, CastEmote = "flex", CastTrigger = "gpower", Describe = (int _) => Loc.F("spell_bearskin_desc", 12f, 40f, 4f, 12f), Cast = CastBearskin }, new Spell { Id = "rage_unbound", UnlockLevel = 50, Cooldown = 120f, Resource = AbilityResource.Fury, ResourceCost = 100f, CastTime = 0f, BaseDamage = 40f, CastEmote = "challenge", CastTrigger = "gpower", Describe = (int lvl) => Loc.F("spell_rage_unbound_desc", Progression.Dmg(40f, lvl), 6f, 12f, 15.000001f), Cast = CastRageUnbound } }; public const float EmptyFuryPenalty = 0.1f; public const float FullFurySpeedBonus = 0.15f; public const float RegenFuryThreshold = 50f; public const float RegenFuryHysteresis = 10f; public const float WrathboundRegenPerTick = 2f; public static string PassiveName => Loc.T("passive_wrathbound_name"); public static string PassiveDescription(int level) { return Loc.F("passive_wrathbound_desc", 10f, MaximumMeleeBonus(level) * 100f, 15.000001f, 50f, 5f); } public static float MaximumMeleeBonus(int level) { return 0.1f + 0.002f * (float)Mathf.Clamp(level, 1, 50); } public static float FuryDamageModifier(Player player, int level) { float num = Mathf.Lerp(-0.1f, MaximumMeleeBonus(level), BerserkerFury.Normalized); if (IsRageUnbound(player)) { num = Mathf.Max(num, 0f) * 2f; } return 1f + num; } public static float FurySpeedMultiplier(Player player) { if ((Object)(object)player == (Object)null || ClassSystem.GetClass(player) != PlayerClass.Berserker) { return 1f; } return 1f + 0.15f * BerserkerFury.Normalized; } public static void Update(Player player) { EnsureState(player); if (!((Object)(object)player == (Object)null)) { bool flag = IsRageUnbound(player); if (_rageWasActive && !flag) { BerserkerFury.EmptyAfterRageUnbound(); } _rageWasActive = flag; if (((Character)player).IsDead()) { _rendingUntil = 0f; _bearskinUntil = 0f; _rageUntil = 0f; } } } public static bool IsRageUnbound(Player player) { if ((Object)(object)player != (Object)null && player == _statePlayer) { return Time.time < _rageUntil; } return false; } private static void EnsureState(Player player) { if (player != _statePlayer) { _statePlayer = player; _rendingUntil = 0f; _rendingExtraDamage = 0f; _bearskinUntil = 0f; _rageUntil = 0f; _rageWasActive = false; _animationAttackPlayer = null; _suppressAnimationAttackUntil = 0f; } } public static void ResetState(Player player) { _statePlayer = player; _rendingUntil = 0f; _rendingExtraDamage = 0f; _bearskinUntil = 0f; _rageUntil = 0f; _rageWasActive = false; _animationAttackPlayer = null; _suppressAnimationAttackUntil = 0f; } public static void ModifyOutgoingMelee(Character target, Player attacker, HitData hit) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0166: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) EnsureState(attacker); int level = ClassSystem.GetLevel(attacker); float num = FuryDamageModifier(attacker, level); num *= BerserkerSpecializationEffects.RendMultiplier(attacker, target); num *= BerserkerSpecializationEffects.CommandMultiplier(attacker); num *= RuneEffects.MeleeDamageMultiplier(attacker); hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; hit.m_staggerMultiplier *= BerserkerSpecializationEffects.OutgoingStaggerMultiplier(attacker); if (BerserkerSpecializationEffects.IsJotunnForm(attacker)) { Vector3 point = ((hit.m_point != Vector3.zero) ? hit.m_point : (((Object)(object)target != (Object)null) ? target.GetCenterPoint() : ((Component)attacker).transform.position)); JotunnClass.ReleaseFormShockwave(attacker, target, point); } RuneEffects.ApplyMeleeRiders(attacker, hit); RuneEffects.OnMeleeHit(attacker, target, hit); if (!(Time.time >= _rendingUntil) && !(_rendingExtraDamage <= 0f)) { hit.m_damage.m_slash += _rendingExtraDamage; hit.m_staggerMultiplier = Mathf.Max(hit.m_staggerMultiplier, 2.2f); _rendingUntil = 0f; _rendingExtraDamage = 0f; PassiveEffects.RemoveRending(attacker); Vector3 b = ((hit.m_point != Vector3.zero) ? hit.m_point : (((Object)(object)target != (Object)null) ? target.GetCenterPoint() : ((Component)attacker).transform.position)); SpellFx.PlayShared(FxKind.RendingBlow, ((Component)attacker).transform.position, b); } } public static void ReduceIncomingDamage(Player player, float previousHealth, ref float health) { if (!((Object)(object)player == (Object)null) && ClassSystem.GetClass(player) == PlayerClass.Berserker) { EnsureState(player); if (!(health >= previousHealth) && !(Time.time >= _bearskinUntil)) { float num = previousHealth - health; health = previousHealth - num * 0.6f; } } } private static void ArmRendingBlow(Player player, int level) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) EnsureState(player); _rendingUntil = Time.time + 8f; _rendingExtraDamage = Progression.Dmg(34f, level); PassiveEffects.ApplyRending(player); SpellFx.PlayShared(FxKind.RendingEmpower, ((Component)player).transform.position, ((Component)player).transform.position); } private static void CastWarCry(Player player, int level) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0015: 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_0047: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)player).transform.position; SpellFx.PlayShared(FxKind.WarCry, position, position); foreach (Character item in Effects.EnemiesInRange(position, 8f, (Character)(object)player)) { Effects.DealDamage(player, item, new DamageTypes { m_blunt = 1f }, null, 40f, 10f); } BerserkerFury.AddFromWarCry(50f); } private static void CastBloodstorm(Player player, int level) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) SpellFx.PlayShared(FxKind.Bloodstorm, ((Component)player).transform.position, ((Component)player).transform.position); ((MonoBehaviour)Plugin.Instance).StartCoroutine(BloodstormRoutine(player, level)); } private static IEnumerator BloodstormRoutine(Player player, int level) { Quaternion startRotation = ((Component)player).transform.rotation; float damage = Progression.Dmg(28f, level); SuppressAnimationAttacks(player, 3.75f); float elapsed = 0f; float nextSwingAt = 0f; int pulsesDealt = 0; while (elapsed < 2.55f) { if ((Object)(object)player == (Object)null) { yield break; } if (((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker) { RestoreFacing(player, startRotation); yield break; } if (elapsed >= nextSwingAt && !((Character)player).InAttack()) { TriggerWeaponSwing(player); nextSwingAt = elapsed + 0.15f; } float num = 4f * (elapsed / 2.55f); ((Component)player).transform.rotation = startRotation * Quaternion.Euler(0f, num * 360f, 0f); int num2 = Mathf.Clamp(Mathf.FloorToInt((elapsed + 0.40799996f) / 0.84999996f), 0, 3); while (pulsesDealt < num2) { pulsesDealt++; DealBloodstormPulse(player, damage); } elapsed += Time.deltaTime; yield return null; } while (pulsesDealt < 3) { pulsesDealt++; DealBloodstormPulse(player, damage); } RestoreFacing(player, startRotation); } internal static void RestoreFacing(Player player, Quaternion fallback) { //IL_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0031: 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_004e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { Quaternion lookYaw = ((Character)player).GetLookYaw(); ((Component)player).transform.rotation = ((lookYaw.x == 0f && lookYaw.y == 0f && lookYaw.z == 0f && lookYaw.w == 0f) ? fallback : lookYaw); } } private static void DealBloodstormPulse(Player player, float damage) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) foreach (Character item in Effects.EnemiesInRange(((Component)player).transform.position, 5f, (Character)(object)player)) { Effects.DealDamage(player, item, new DamageTypes { m_slash = damage }, null, 12f); } } internal static void SuppressAnimationAttacks(Player player, float duration) { if (!((Object)(object)player == (Object)null)) { _animationAttackPlayer = player; _suppressAnimationAttackUntil = Mathf.Max(_suppressAnimationAttackUntil, Time.time + duration); } } internal static void TriggerWeaponSwing(Player player) { if ((Object)(object)player == (Object)null) { return; } float stamina = player.GetStamina(); if (((Character)player).StartAttack((Character)null, false)) { SuppressAnimationAttacks(player, 0.9f); float num = stamina - player.GetStamina(); if (num > 0f) { ((Character)player).AddStamina(num); } } else { ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); string text = ((currentWeapon != null && currentWeapon.m_shared != null && currentWeapon.m_shared.m_attack != null) ? currentWeapon.m_shared.m_attack.m_attackAnimation : null); if (!string.IsNullOrEmpty(text) && (Object)(object)((Character)player).m_zanim != (Object)null) { ((Character)player).m_zanim.SetTrigger(text); } } } internal static bool SuppressAnimationAttack(Attack attack) { if (attack != null && Time.time < _suppressAnimationAttackUntil) { return (object)attack.m_character == _animationAttackPlayer; } return false; } private static void CastBearskin(Player player, int level) { //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) EnsureState(player); _bearskinUntil = Time.time + 12f; PassiveEffects.ApplyBearskin(player); SpellFx.PlayShared(FxKind.Bearskin, ((Component)player).transform.position, ((Component)player).transform.position); XpSystem.Message(player, Loc.T("msg_bearskin_taunt")); ((MonoBehaviour)Plugin.Instance).StartCoroutine(BearskinRoutine(player)); } private static IEnumerator BearskinRoutine(Player player) { for (float elapsed = 0f; elapsed < 12f; elapsed += 1.5f) { if ((Object)(object)player == (Object)null) { break; } if (((Character)player).IsDead()) { break; } if (player != _statePlayer) { break; } Vector3 position = ((Component)player).transform.position; ZDOID zDOID = ((Character)player).GetZDOID(); Effects.TauntOwned(position, 12f, zDOID); Network.BroadcastTaunt(position, 12f, zDOID); float num = Mathf.Max(0f, ((Character)player).GetMaxHealth() - ((Character)player).GetHealth()); if (num > 0.01f) { ((Character)player).Heal(Mathf.Min(num, 6f), true); } yield return (object)new WaitForSeconds(1.5f); } } private static void CastRageUnbound(Player player, int level) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) EnsureState(player); _rageUntil = Time.time + 12f; _rageWasActive = true; PassiveEffects.ApplyRageUnbound(player); BerserkerFury.FillForRageUnbound(); SpellFx.PlayShared(FxKind.RageUnbound, ((Component)player).transform.position, ((Component)player).transform.position); } } [HarmonyPatch(typeof(SEMan), "ApplyStatusEffectSpeedMods")] internal static class BerserkerFurySpeedPatch { private static void Postfix(SEMan __instance, ref float speed) { Character obj = __instance?.m_character; Player val = (Player)(object)((obj is Player) ? obj : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { speed *= BerserkerClass.FurySpeedMultiplier(val); } } } [HarmonyPatch(typeof(Attack), "DoMeleeAttack")] internal static class BerserkerAnimationMeleePatch { private static bool Prefix(Attack __instance) { return !BerserkerClass.SuppressAnimationAttack(__instance); } } [HarmonyPatch(typeof(Attack), "DoAreaAttack")] internal static class BerserkerAnimationAreaPatch { private static bool Prefix(Attack __instance) { return !BerserkerClass.SuppressAnimationAttack(__instance); } } public static class BerserkerFury { public const float Maximum = 100f; public const float GraceDuration = 5f; public const float DecayPerSecond = 3.75f; private const float TwoHandedFuryScale = 1.35f; private const float OneHandedFuryScale = 0.78f; private static Player _trackedPlayer; private static float _value; private static float _lastCombatAt = -999f; private static bool _wasDead; public static float Value => _value; public static float Normalized => Mathf.Clamp01(_value / 100f); public static void Update(Player player) { if (player != _trackedPlayer) { _trackedPlayer = player; _value = 0f; _lastCombatAt = -999f; _wasDead = false; } if ((Object)(object)player == (Object)null || ClassSystem.GetClass(player) != PlayerClass.Berserker) { _value = 0f; return; } if (((Character)player).IsDead()) { if (!_wasDead) { _value = 0f; } _wasDead = true; return; } _wasDead = false; if (MaximumIsLocked(player)) { _value = 100f; } else if (Time.time - _lastCombatAt > 5f) { float num = RuneEffects.FuryDecay(player, 3.75f); _value = Mathf.MoveTowards(_value, 0f, num * Time.deltaTime); } PassiveEffects.RefreshWrathbound(player); } public static bool Has(float amount) { if (!MaximumIsLocked(Player.m_localPlayer)) { return _value + 0.001f >= Mathf.Max(0f, amount); } return true; } public static bool Spend(float amount) { if (!Has(amount)) { return false; } TouchCombat(); if (!MaximumIsLocked(Player.m_localPlayer)) { _value = Mathf.Max(0f, _value - Mathf.Max(0f, amount)); } return true; } public static void AddFromWarCry(float amount) { Add(amount); } public static void FillForRageUnbound() { _value = 100f; TouchCombat(); } public static void EmptyAfterRageUnbound() { _value = 0f; _lastCombatAt = Time.time; } public static void Reset(Player player) { _trackedPlayer = player; _value = 0f; _lastCombatAt = -999f; _wasDead = (Object)(object)player != (Object)null && ((Character)player).IsDead(); } public static void AddFromDamageDealt(float effectiveDamage) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ClassSystem.GetClass(localPlayer) != PlayerClass.Berserker || effectiveDamage <= 0.01f) { return; } float num = Mathf.Clamp(2f + Mathf.Sqrt(effectiveDamage) * 0.75f, 2f, 14f); Add(RuneEffects.FuryGain(localPlayer, num * WeaponFuryScale(localPlayer))); float num2 = 0f; if (BerserkerClass.IsRageUnbound(localPlayer)) { num2 = 0.15f; } if (BerserkerSpecializationEffects.IsBloodlust(localPlayer)) { num2 = Mathf.Max(num2, 0.25f); } if (num2 > 0f) { float num3 = Mathf.Max(0f, ((Character)localPlayer).GetMaxHealth() - ((Character)localPlayer).GetHealth()); if (num3 > 0.01f) { ((Character)localPlayer).Heal(Mathf.Min(num3, effectiveDamage * num2), true); } } } public static void AddFromDamageTaken(float effectiveDamage) { if (!(effectiveDamage <= 0.01f)) { Add(Mathf.Clamp(10f + effectiveDamage * 0.16f, 10f, 26f)); } } private static float WeaponFuryScale(Player player) { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 ItemData val = ((player != null) ? ((Humanoid)player).GetCurrentWeapon() : null); if (val == null || val.m_shared == null) { return 1f; } ItemType itemType = val.m_shared.m_itemType; if ((int)itemType == 14 || (int)itemType == 22) { return 1.35f; } return 0.78f; } private static void Add(float amount) { if (MaximumIsLocked(Player.m_localPlayer)) { _value = 100f; } else { _value = Mathf.Clamp(_value + Mathf.Max(0f, amount), 0f, 100f); } TouchCombat(); } private static void TouchCombat() { _lastCombatAt = Time.time; } private static bool MaximumIsLocked(Player player) { return BerserkerClass.IsRageUnbound(player); } internal static bool IsMeleeSkill(SkillType skill) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if ((int)skill != 1 && (int)skill != 2 && (int)skill != 3 && (int)skill != 4 && (int)skill != 5 && (int)skill != 7) { return (int)skill == 11; } return true; } internal static bool IsValidCombatTarget(Character target, Player attacker) { if ((Object)(object)target == (Object)null || (Object)(object)attacker == (Object)null || target.IsPlayer() || target.IsTamed()) { return false; } string text = (((Object)(object)target.m_nview != (Object)null) ? target.m_nview.GetPrefabName() : ((Object)((Component)target).gameObject).name); if (!string.IsNullOrEmpty(text) && text.IndexOf("TrainingDummy", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } return BaseAI.IsEnemy(target, (Character)(object)attacker); } internal static void AwardDealtDamageFromWitness(long playerId, float effectiveDamage, SkillType skill) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (playerId != 0L && !(effectiveDamage <= 0.01f) && IsMeleeSkill(skill)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && localPlayer.GetPlayerID() == playerId) { AddFromDamageDealt(effectiveDamage); } Network.BroadcastFuryHit(playerId, effectiveDamage); } } internal static void ReceiveRemoteHit(long playerId, float effectiveDamage) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && localPlayer.GetPlayerID() == playerId) { AddFromDamageDealt(effectiveDamage); } } } [HarmonyPatch(typeof(Character), "Damage")] public static class BerserkerOutgoingDamagePatch { private static void Prefix(Character __instance, HitData hit) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (hit != null && BerserkerFury.IsMeleeSkill(hit.m_skill)) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && ClassSystem.GetClass(val) == PlayerClass.Berserker) { BerserkerClass.ModifyOutgoingMelee(__instance, val, hit); } } } } [HarmonyPatch(typeof(Character), "SetHealth")] public static class BerserkerIncomingDamagePatch { private static void Prefix(Character __instance, ref float health) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { float health2 = ((Character)val).GetHealth(); if (!(health >= health2 - 0.01f)) { BerserkerSpecializationEffects.ReduceIncomingDamage(val, health2, ref health); BerserkerClass.ReduceIncomingDamage(val, health2, ref health); RuneEffects.ReduceIncomingDamage(val, health2, ref health); BloodMageClass.AbsorbIncomingDamage(val, health2, ref health); } } } } [HarmonyPatch(typeof(Character), "AddStaggerDamage")] public static class JotunnStaggerResistancePatch { private static void Prefix(Character __instance, ref float damage) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { damage *= BerserkerSpecializationEffects.IncomingStaggerMultiplier(val); } } } [HarmonyPatch(typeof(Character), "ApplyPushback", new Type[] { typeof(Vector3), typeof(float) })] public static class JotunnPushResistancePatch { private static void Prefix(Character __instance, ref float pushForce) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { pushForce *= BerserkerSpecializationEffects.IncomingPushMultiplier(val); } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class BerserkerIncomingDamageWitnessPatch { private struct DamageState { public Player Player; public float HealthBefore; public bool Hostile; } private static void Prefix(Character __instance, HitData hit, out DamageState __state) { __state = default(DamageState); Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && hit != null && ClassSystem.GetClass(val) == PlayerClass.Berserker && !((Object)(object)((Character)val).m_nview == (Object)null) && ((Character)val).m_nview.IsOwner()) { Character attacker = hit.GetAttacker(); __state.Player = val; __state.HealthBefore = ((Character)val).GetHealth(); __state.Hostile = (Object)(object)attacker != (Object)null && (Object)(object)attacker != (Object)(object)val && BaseAI.IsEnemy(attacker, (Character)(object)val); } } private static void Postfix(DamageState __state) { if (__state.Hostile && !((Object)(object)__state.Player == (Object)null)) { float effectiveDamage = Mathf.Max(0f, __state.HealthBefore - ((Character)__state.Player).GetHealth()); BerserkerFury.AddFromDamageTaken(effectiveDamage); RuneEffects.OnDamageTaken(__state.Player, effectiveDamage); } } } public sealed class BerserkerImpactVfxController : MonoBehaviour { public Light ImpactLight; public float LightIntensity = 2.2f; public float Lifetime = 3.2f; private float _startedAt; private void OnEnable() { _startedAt = Time.time; BerserkerVfxSupport.Play(((Component)this).transform); if ((Object)(object)ImpactLight != (Object)null) { ImpactLight.intensity = 0f; ((Behaviour)ImpactLight).enabled = true; } } private void LateUpdate() { float num = Time.time - _startedAt; if ((Object)(object)ImpactLight != (Object)null && ((Behaviour)ImpactLight).enabled) { float num2 = BerserkerVfxSupport.Flash(num, 0.025f, 0.28f) * LightIntensity; ImpactLight.intensity = num2; if (num2 <= 0.001f && num > 0.5f) { ((Behaviour)ImpactLight).enabled = false; } } if (num >= Lifetime) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public static class BerserkerSpecializationEffects { public const string RendName = "SE_Norns_Rend"; public const string MaimName = "SE_Norns_Maim"; public const string MountainSlowName = "SE_Norns_Mountainform"; public const float RendVulnerability = 0.3f; public const float MaimSlow = 0.4f; public const float BloodlustDuration = 12f; public const float BloodlustLifeSteal = 0.25f; public const float SlaughterDuration = 12f; public const float SlaughterSpreadRadius = 6f; public const string GraspName = "SE_Norns_TitansGrasp"; public const float GraspSlow = 0.35f; public const float BedrockDamageReduction = 0.12f; public const float BedrockStaggerResistance = 0.4f; public const float BedrockPushResistance = 0.4f; public const string RallyName = "SE_Norns_RallyStandard"; public const string WardingName = "SE_Norns_WardingStandard"; public const string WarbandStandsName = "SE_Norns_WarbandStands"; public const string SunderedName = "SE_Norns_Sundered"; public const float RallyDamageBonus = 1.15f; public const float WardingArmor = 30f; public const float WarbandStandsArmor = 18f; public const float WarbandStandsRegenPerTick = 3f; public const float SunderedSlow = 0.3f; public const float CommandDamageBonus = 0.12f; public const float CommandDamageReduction = 0.12f; public const string WarlordAuraName = "SE_Norns_WarlordAura"; public const float WarlordAuraRadius = 15f; public const float WarlordAuraMaxBonus = 0.1f; public const int WarlordAuraTiers = 4; private static Player _statePlayer; private static float _bloodlustUntil; private static float _slaughterUntil; private static float _mountainUntil; private static float _jotunnFormUntil; public static void ResetState(Player player) { _statePlayer = player; _bloodlustUntil = 0f; _slaughterUntil = 0f; _mountainUntil = 0f; _jotunnFormUntil = 0f; } public static void Update(Player player) { EnsureState(player); if (!((Object)(object)player == (Object)null)) { if (((Character)player).IsDead()) { _bloodlustUntil = 0f; _slaughterUntil = 0f; _mountainUntil = 0f; _jotunnFormUntil = 0f; } RavagerClass.UpdateWounds(player); ApplyMountainSlow(player); WarlordClass.UpdateLocalStandards(player); WarlordClass.UpdateLocalAura(player); WarlordClass.UpdateAura(player); } } private static void EnsureState(Player player) { if (player != _statePlayer) { _statePlayer = player; _bloodlustUntil = 0f; _slaughterUntil = 0f; _mountainUntil = 0f; _jotunnFormUntil = 0f; RavagerClass.ClearWounds(); } } public static bool IsSpecialized(Player player, BerserkerSpecialization thread) { if ((Object)(object)player != (Object)null && ClassSystem.GetClass(player) == PlayerClass.Berserker && ClassSystem.GetLevel(player) >= 50) { return ClassSystem.GetBerserkerSpecialization(player) == thread; } return false; } public static bool IsBloodlust(Player player) { if ((Object)(object)player != (Object)null && player == _statePlayer) { return Time.time < _bloodlustUntil; } return false; } public static bool IsSlaughter(Player player) { if ((Object)(object)player != (Object)null && player == _statePlayer) { return Time.time < _slaughterUntil; } return false; } public static void BeginBloodlust(Player player) { EnsureState(player); _bloodlustUntil = Time.time + 12f; } public static void BeginSlaughter(Player player) { EnsureState(player); _slaughterUntil = Time.time + 12f; } public static bool IsMountainform(Player player) { if ((Object)(object)player != (Object)null && player == _statePlayer) { return Time.time < _mountainUntil; } return false; } public static bool IsJotunnForm(Player player) { if ((Object)(object)player != (Object)null && player == _statePlayer) { return Time.time < _jotunnFormUntil; } return false; } public static void BeginMountainform(Player player) { EnsureState(player); _mountainUntil = Time.time + 12f; } public static void BeginJotunnForm(Player player) { EnsureState(player); _jotunnFormUntil = Time.time + 15f; } private static void ApplyMountainSlow(Player player) { if (((Character)player).m_seman == null) { return; } int stableHashCode = StringExtensionMethods.GetStableHashCode("SE_Norns_Mountainform"); if (IsMountainform(player)) { if (!((Character)player).m_seman.HaveStatusEffect(stableHashCode)) { ((Character)player).m_seman.AddStatusEffect(stableHashCode, true, 0, 0f); } } else if (((Character)player).m_seman.HaveStatusEffect(stableHashCode)) { ((Character)player).m_seman.RemoveStatusEffect(stableHashCode, true); } } public static void ReduceIncomingDamage(Player player, float previousHealth, ref float health) { if (health >= previousHealth) { return; } float num = 1f; if (IsSpecialized(player, BerserkerSpecialization.Jotunn)) { num *= 0.88f; if (IsMountainform(player)) { num *= 0.5f; } } else if (IsUnderCommand(player)) { num *= 0.88f; } if (!(num >= 1f)) { float num2 = previousHealth - health; health = previousHealth - num2 * num; } } public static float IncomingStaggerMultiplier(Player player) { if (!IsSpecialized(player, BerserkerSpecialization.Jotunn)) { return 1f; } if (IsMountainform(player)) { return 0f; } return 0.6f; } public static float IncomingPushMultiplier(Player player) { if (!IsSpecialized(player, BerserkerSpecialization.Jotunn)) { return 1f; } if (IsMountainform(player) || IsJotunnForm(player)) { return 0f; } return 0.6f; } public static float OutgoingStaggerMultiplier(Player player) { if (!IsJotunnForm(player)) { return 1f; } return 2f; } public static int WarlordAuraTierFor(float furyNormalized) { return Mathf.Clamp(Mathf.CeilToInt(furyNormalized * 4f), 0, 4); } public static string WarlordAuraStatus(int tier) { if (tier > 0) { return "SE_Norns_WarlordAura" + tier; } return null; } public static string StandardStatusFor(WarlordClass.StandardKind kind) { return kind switch { WarlordClass.StandardKind.Rally => "SE_Norns_RallyStandard", WarlordClass.StandardKind.Warding => "SE_Norns_WardingStandard", WarlordClass.StandardKind.WarbandStands => "SE_Norns_WarbandStands", _ => null, }; } public static bool IsUnderCommand(Player player) { if (!IsSpecialized(player, BerserkerSpecialization.Warlord)) { return false; } if (((Character)player).m_seman == null) { return false; } if (!((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_RallyStandard")) && !((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_WardingStandard"))) { return ((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_WarbandStands")); } return true; } public static float CommandMultiplier(Player caster) { if (!IsUnderCommand(caster)) { return 1f; } return 1.12f; } public static float RendMultiplier(Player caster, Character target) { if ((Object)(object)caster == (Object)null || (Object)(object)target == (Object)null || target.m_seman == null) { return 1f; } if (RavagerClass.IsResolvingWound) { return 1f; } if (!IsSpecialized(caster, BerserkerSpecialization.Ravager)) { return 1f; } if (!target.m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Norns_Rend"))) { return 1f; } return 1.3f; } public static void RegisterStatusEffects(Action<StatusEffect> register) { //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) if (register != null) { RendStatusEffect rendStatusEffect = ScriptableObject.CreateInstance<RendStatusEffect>(); ((Object)rendStatusEffect).name = "SE_Norns_Rend"; ((StatusEffect)rendStatusEffect).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Rend"); ((StatusEffect)rendStatusEffect).m_name = Loc.Token("status_rend_name"); ((StatusEffect)rendStatusEffect).m_tooltip = Loc.Token("status_rend_tooltip"); ((StatusEffect)rendStatusEffect).m_ttl = 10f; register((StatusEffect)(object)rendStatusEffect); SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val).name = "SE_Norns_Maim"; ((StatusEffect)val).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Maim"); ((StatusEffect)val).m_name = Loc.Token("status_maimed_name"); ((StatusEffect)val).m_tooltip = Loc.Token("status_maimed_tooltip"); ((StatusEffect)val).m_ttl = 5f; val.m_speedModifier = -0.4f; register((StatusEffect)(object)val); SE_Stats val2 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val2).name = "SE_Norns_TitansGrasp"; ((StatusEffect)val2).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_TitansGrasp"); ((StatusEffect)val2).m_name = Loc.Token("status_titans_grasp_name"); ((StatusEffect)val2).m_tooltip = Loc.Token("status_titans_grasp_tooltip"); ((StatusEffect)val2).m_ttl = 4f; val2.m_speedModifier = -0.35f; register((StatusEffect)(object)val2); SE_Stats val3 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val3).name = "SE_Norns_Mountainform"; ((StatusEffect)val3).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Mountainform"); ((StatusEffect)val3).m_name = Loc.Token("status_mountainform_name"); ((StatusEffect)val3).m_tooltip = Loc.Token("status_mountainform_tooltip"); ((StatusEffect)val3).m_ttl = 0f; ((StatusEffect)val3).m_icon = SpellIcons.StatusFor(JotunnClass.Mountainform); val3.m_speedModifier = -0.25f; register((StatusEffect)(object)val3); SE_Stats val4 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val4).name = "SE_Norns_RallyStandard"; ((StatusEffect)val4).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_RallyStandard"); ((StatusEffect)val4).m_name = Loc.Token("status_rally_standard_name"); ((StatusEffect)val4).m_tooltip = Loc.Formatted("status_rally_standard_tooltip", 14.999998f); ((StatusEffect)val4).m_ttl = 0f; ((StatusEffect)val4).m_icon = SpellIcons.StatusFor(WarlordClass.RallyStandard); val4.m_modifyAttackSkill = (SkillType)999; val4.m_damageModifier = 1.15f; register((StatusEffect)(object)val4); SE_Stats val5 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val5).name = "SE_Norns_WardingStandard"; ((StatusEffect)val5).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_WardingStandard"); ((StatusEffect)val5).m_name = Loc.Token("status_warding_standard_name"); ((StatusEffect)val5).m_tooltip = Loc.Formatted("status_warding_standard_tooltip", 30f); ((StatusEffect)val5).m_ttl = 0f; ((StatusEffect)val5).m_icon = SpellIcons.StatusFor(WarlordClass.WardingStandard); val5.m_addArmor = 30f; register((StatusEffect)(object)val5); SE_Stats val6 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val6).name = "SE_Norns_WarbandStands"; ((StatusEffect)val6).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_WarbandStands"); ((StatusEffect)val6).m_name = Loc.Token("status_warband_stands_name"); ((StatusEffect)val6).m_tooltip = Loc.Formatted("status_warband_stands_tooltip", 18f); ((StatusEffect)val6).m_ttl = 0f; ((StatusEffect)val6).m_icon = SpellIcons.StatusFor(WarlordClass.TheWarbandStands); val6.m_addArmor = 18f; val6.m_tickInterval = 1f; val6.m_healthPerTick = 3f; register((StatusEffect)(object)val6); for (int i = 1; i <= 4; i++) { float num = (float)i / 4f; string text = "SE_Norns_WarlordAura" + i; SE_Stats val7 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val7).name = text; ((StatusEffect)val7).m_nameHash = StringExtensionMethods.GetStableHashCode(text); ((StatusEffect)val7).m_name = Loc.Token("status_warlord_aura_name"); ((StatusEffect)val7).m_tooltip = Loc.Formatted("status_warlord_aura_tooltip", 0.1f * num * 100f); ((StatusEffect)val7).m_ttl = 0f; ((StatusEffect)val7).m_icon = SpellIcons.StatusFor(WarlordClass.RallyStandard); val7.m_modifyAttackSkill = (SkillType)999; val7.m_damageModifier = 1f + 0.1f * num; val7.m_speedModifier = 0.1f * num; register((StatusEffect)(object)val7); } SE_Stats val8 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val8).name = "SE_Norns_Sundered"; ((StatusEffect)val8).m_nameHash = StringExtensionMethods.GetStableHashCode("SE_Norns_Sundered"); ((StatusEffect)val8).m_name = Loc.Token("status_sundered_name"); ((StatusEffect)val8).m_tooltip = Loc.Token("status_sundered_tooltip"); ((StatusEffect)val8).m_ttl = 2.2f; val8.m_speedModifier = -0.3f; register((StatusEffect)(object)val8); } } } public sealed class RendStatusEffect : StatusEffect { public override void SetLevel(int itemLevel, float skillLevel) { ((StatusEffect)this).SetLevel(itemLevel, skillLevel); if (skillLevel > 0.01f) { base.m_ttl = skillLevel; } } } public static class BerserkerSpecializations { public const float ExecutionRange = 7f; public const float ExecutionDamage = 70f; public const float ExecutionLowHealthMultiplier = 2.2f; public const float ExecutionThreshold = 0.5f; public const float EarthshatterRadius = 10f; public const float EarthshatterDamage = 75f; public const float EarthshatterRange = 16f; public const float EarthshatterMinRange = 6f; public const float EarthshatterApexHeight = 15f; public const float EarthshatterDiveVelocity = 28f; public const float WarbandRadius = 15f; public const float WarbandDuration = 12f; public const int WarbandSpiritCount = 3; public const float WarbandSpiritDamage = 6f; public static readonly BerserkerSpecialization[] All = new BerserkerSpecialization[3] { BerserkerSpecialization.Ravager, BerserkerSpecialization.Jotunn, BerserkerSpecialization.Warlord }; public static readonly BerserkerSpecialization[] Choices = new BerserkerSpecialization[4] { BerserkerSpecialization.None, BerserkerSpecialization.Ravager, BerserkerSpecialization.Jotunn, BerserkerSpecialization.Warlord }; private static readonly Spell RavagerSpell = new Spell { Id = "executioners_wake", UnlockLevel = 50, Cooldown = 60f, Resource = AbilityResource.Fury, ResourceCost = 70f, CastTime = 0f, BaseDamage = 70f, CastTrigger = null, Describe = (int lvl) => Loc.F("spell_executioners_wake_desc", Progression.Dmg(70f, lvl), 50f, 2.2f), Cast = CastExecutionersWake }; private static readonly Spell JotunnSpell = new Spell { Id = "earthshatter", UnlockLevel = 50, Cooldown = 70f, Resource = AbilityResource.Fury, ResourceCost = 80f, CastTime = 0f, BaseDamage = 75f, CastTrigger = null, Describe = (int lvl) => Loc.F("spell_earthshatter_desc", 16f, Progression.Dmg(75f, lvl), 10f), Cast = CastEarthshatter }; private static readonly Spell WarlordSpell = new Spell { Id = "warbands_oath", UnlockLevel = 50, Cooldown = 120f, Resource = AbilityResource.Fury, ResourceCost = 60f, CastTime = 0f, BaseDamage = 6f, CastEmote = "roar", CastTrigger = "gpower", Describe = (int lvl) => Loc.F("spell_warbands_oath_desc", 3, 12f), Cast = CastWarbandsOath }; public static void ResetState(Player player) { WarbandSpirit.DismissOwned(player); WarlordClass.ResetState(player); } public static Spell SpellFor(BerserkerSpecialization specialization) { return specialization switch { BerserkerSpecialization.Ravager => RavagerSpell, BerserkerSpecialization.Jotunn => JotunnSpell, BerserkerSpecialization.Warlord => WarlordSpell, _ => null, }; } public static Spell CoreSpellFor(Player player, int index, Spell core) { if (core == null || (Object)(object)player == (Object)null || ClassSystem.GetLevel(player) < 50) { return core; } switch (ClassSystem.GetBerserkerSpecialization(player)) { case BerserkerSpecialization.Ravager: if (index < 0 || index >= RavagerClass.Spells.Length) { return core; } return RavagerClass.Spells[index]; case BerserkerSpecialization.Jotunn: if (index < 0 || index >= JotunnClass.Spells.Length) { return core; } return JotunnClass.Spells[index]; case BerserkerSpecialization.Warlord: if (index < 0 || index >= WarlordClass.Spells.Length) { return core; } return WarlordClass.Spells[index]; default: return core; } } public static string NameOf(BerserkerSpecialization specialization) { return Loc.T("spec_berserker_" + KeyOf(specialization) + "_name"); } private static string KeyOf(BerserkerSpecialization specialization) { return specialization switch { BerserkerSpecialization.Ravager => "ravager", BerserkerSpecialization.Jotunn => "jotunn", BerserkerSpecialization.Warlord => "warlord", _ => "none", }; } public static string DescriptionOf(BerserkerSpecialization specialization) { return Loc.T("spec_berserker_" + KeyOf(specialization) + "_desc"); } public static Color AccentOf(BerserkerSpecialization specialization) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) return (Color)(specialization switch { BerserkerSpecialization.Ravager => new Color(0.96f, 0.18f, 0.12f), BerserkerSpecialization.Jotunn => new Color(0.66f, 0.63f, 0.58f), BerserkerSpecialization.Warlord => new Color(0.94f, 0.68f, 0.24f), _ => ClassArt.AccentOf(PlayerClass.Berserker), }); } public static string ShortNameOf(BerserkerSpecialization specialization) { return Loc.T("spec_berserker_" + KeyOf(specialization) + "_short"); } private static void CastExecutionersWake(Player player, int level) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_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_0051: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) Vector3 position = ((Component)player).transform.position; Vector3 val = Effects.AimDirection(player); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = ((Component)player).transform.forward; } ((Vector3)(ref val)).Normalize(); Vector3 b = position + val * 7f; ((Component)player).transform.rotation = Quaternion.LookRotation(val, Vector3.up); BerserkerClass.TriggerWeaponSwing(player); SpellFx.PlayShared(FxKind.ExecutionersWake, position, b); ((MonoBehaviour)Plugin.Instance).StartCoroutine(ExecutionersWakeDamage(player, level, val)); } private static IEnumerator ExecutionersWakeDamage(Player player, int level, Vector3 forward) { //IL_0015: 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) yield return (object)new WaitForSeconds(0.2f); if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker) { yield break; } Vector3 position = ((Component)player).transform.position; float num = Progression.Dmg(70f, level); foreach (Character item in Effects.EnemiesInRange(position, 7f, (Character)(object)player)) { Vector3 val = ((Component)item).transform.position - position; val.y = 0f; if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f) || !(Vector3.Dot(forward, ((Vector3)(ref val)).normalized) < 0.57f)) { float slash = ((((item.GetMaxHealth() > 0f) ? (item.GetHealth() / item.GetMaxHealth()) : 1f) <= 0.5f) ? (num * 2.2f) : num); Effects.DealDamage(player, item, new DamageTypes { m_slash = slash }, null, 30f); } } } private static void CastEarthshatter(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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = EarthshatterTarget(player); Vector3 val2 = val - ((Component)player).transform.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = ((Component)player).transform.forward; } ((Vector3)(ref val2)).Normalize(); ((Component)player).transform.rotation = Quaternion.LookRotation(val2, Vector3.up); ((MonoBehaviour)Plugin.Instance).StartCoroutine(EarthshatterLeap(player, level, val)); } private static Vector3 EarthshatterTarget(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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) //IL_0083: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)player).transform.position; Vector3 val = Effects.AimDirection(player); Vector3 val2 = val; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = ((Component)player).transform.forward; } ((Vector3)(ref val2)).Normalize(); float num = Mathf.Lerp(6f, 16f, Mathf.Clamp01(((Vector3)(ref val2)).magnitude * (1f - Mathf.Clamp01(0f - val.y)))); num = Mathf.Clamp(num, 6f, 16f); return Effects.SurfacePoint(position + val2 * num); } private static IEnumerator EarthshatterLeap(Player player, int level, Vector3 targetSurface) { //IL_0015: 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) if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || ClassSystem.GetClass(player) != PlayerClass.Berserker || (Object)(object)((Character)player).m_body == (Object)null) { yield break; } if ((Object)(object)((Character)player).m_zanim != (Object)null) { ((Character)player).m_zanim.SetTrigger("jump"); } Vector3 start = ((Character)player).m_body.position; float num = Mathf.Clamp(start.y - Effects.SurfacePoint(start).y, 0.05f, 0.8f); Vector3 target = targetSurface + Vector3.up * num; Vector3 apex = Vector3.Lerp(start, target, 0.44f); apex.y = Mathf.Max(start.y, target.y) + 15f; float elapsed = 0f; while (elapsed < 0.9f) { yield return (object)new WaitForFixedUpdate(); if (!CanContinueEarthshatter(player)) { yield break; } elapsed += Time.fixedDeltaTime; float num2 = Mathf.Clamp01(elapsed / 0.9f); float num3 = num2 * num2 * (3f - 2f * num2); MoveEarthshatterBody(player, Vector3.Lerp(start, apex, num3)); } float holdUntil = Time.time + 0.1f; while (Time.time < holdUntil) { yield return (object)new WaitForFixedUpdate(); if (!CanContinueEarthshatter(player)) { yield break; } MoveEarthshatterBody(player, apex); } SpellFx.PlayShared(FxKind.EarthshatterDive, ((Component)player).transform.position, targetSurface); BerserkerClass.SuppressAnimationAttacks(player, 1.6f); BerserkerClass.TriggerWeaponSwing(player); Vector3 diveStart = ((Character)player).m_body.position; float diveDuration = Mathf.Clamp(Vector3.Distance(diveStart, target) / 28f, 0.46f, 0.82f); elapsed = 0f; while (elapsed < diveDuration) { yield return (object)new WaitForFixedUpdate(); if (!CanContinueEarthshatter(player)) { yield break; } elapsed += Time.fixedDeltaTime; float num4 = Mathf.Clamp01(elapsed / diveDuration); float num5 = num4 * num4; MoveEarthshatterBody(player, Vector3.Lerp(diveStart, target, num5)); } if (!CanContinueEarthshatter(player)) { yield break; } MoveEarthshatterBody(player, target); yield return (object)new WaitForFixedUpdate(); if (!CanContinueEarthshatter(player)) { yield break; } ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; ((Character)player).m_body.linearVelocity = Vector3.zero; Vector3 val = Effects.SurfacePoint(targetSurface); SpellFx.PlayShared(FxKind.Earthshatter, val, val); float blunt = Progression.Dmg(75f, level); foreach (Character item in Effects.EnemiesInRange(val, 10f, (Character)(object)player)) { Effects.DealDamage(player, item, new DamageTypes { m_blunt = blunt }, null, 75f); } } private static void MoveEarthshatterBody(Player player, Vector3 position) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) float num = Mathf.Max(0.001f, Time.fixedDeltaTime); ((Character)player).m_body.linearVelocity = (position - ((Character)player).m_body.position) / num; ((Character)player).m_body.MovePosition(position); ((Character)player).m_maxAirAltitude = ((Component)player).transform.position.y; } private static bool CanContinueEarthshatter(Player player) { if ((Object)(object)player != (Object)null && !((Character)player).IsDead() && (Object)(object)((Character)player).m_body != (Object)null) { return ClassSystem.GetClass(player) == PlayerClass.Berserker; } return false; } private static void CastWarbandsOath(Player player, int level) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 position = ((Component)player).transform.position; SpellFx.PlayShared(FxKind.WarbandsOath, position, position); if (!WarbandSpirit.Ready) { XpSystem.Message(player, Loc.T("msg_warband_no_answer")); return; } WarbandSpirit.DismissOwned(player); WarbandSpirit.Summon(player, 3, Progression.Dmg(6f, level), 12f); XpSystem.Message(player, "Warband's Oath — the fallen answer"); } } internal static class BerserkerVfxSupport { public static Player FindNearestPlayer(Vector3 position, float maximumDistance = 4.5f) { //IL_0022: 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) Player result = null; float num = maximumDistance; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null)) { float num2 = Vector3.Distance(position, ((Component)allPlayer).transform.position); if (!(num2 >= num)) { num = num2; result = allPlayer; } } } return result; } public static Transform ChestAnchor(Player player) { if ((Object)(object)player == (Object)null) { return null; } Animator componentInChildren = ((Component)player).GetComponentInChildren<Animator>(); if ((Object)(object)componentInChildren == (Object)null || !componentInChildren.isHuman) { return null; } return componentInChildren.GetBoneTransform((HumanBodyBones)54) ?? componentInChildren.GetBoneTransform((HumanBodyBones)8) ?? componentInChildren.GetBoneTransform((HumanBodyBones)7); } public static void Play(Transform group) { if ((Object)(object)group == (Object)null) { return; } ParticleSystem[] componentsInChildren = ((Component)group).GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.Play(true); } } } public static void StopEmitting(Transform group) { if ((Object)(object)group == (Object)null) { return; } ParticleSystem[] componentsInChildren = ((Component)group).GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.Stop(true, (ParticleSystemStopBehavior)1); } } } public static void StopAndClear(Transform group) { if ((Object)(object)group == (Object)null) { return; } ParticleSystem[] componentsInChildren = ((Component)group).GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.Stop(true, (ParticleSystemStopBehavior)0); } } } public static float Smooth01(float value) { value = Mathf.Clamp01(value); return value * value * (3f - 2f * value); } public static float Flash(float elapsed, float attack, float decay) { if (elapsed < 0f) { return 0f; } if (elapsed < attack) { return Smooth01(elapsed / Mathf.Max(0.0001f, attack)); } return 1f - Smooth01((elapsed - attack) / Mathf.Max(0.0001f, decay)); } } public static class BerserkerWeapons { public const string UruzCleaverPrefab = "NornsUruzCleaver"; private static bool _hooked; private static bool _created; public static void Register() { if (!_hooked) { _hooked = true; PrefabManager.OnVanillaPrefabsAvailable += Create; } } public static void Shutdown() { if (_hooked) { PrefabManager.OnVanillaPrefabsAvailable -= Create; } _hooked = false; } private static void Create() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= Create; _hooked = false; if (_created) { return; } try { ItemConfig val = new ItemConfig(); val.Name = Loc.Token("item_uruz_cleaver_name"); val.Description = Loc.Token("item_uruz_cleaver_desc"); val.CraftingStation = CraftingStations.Workbench; val.RepairStation = CraftingStations.Workbench; val.MinStationLevel = 1; val.Weight = 4.5f; val.Icon = LoadIcon("uruz_cleaver.jpg"); val.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig("Wood", 12, 4, true), new RequirementConfig("Flint", 8, 4, true), new RequirementConfig("LeatherScraps", 4, 2, true), new RequirementConfig("DeerHide", 2, 1, true) }; ItemConfig val2 = val; CustomItem val3 = new CustomItem("NornsUruzCleaver", "Battleaxe", val2); if ((Object)(object)val3.ItemPrefab == (Object)null || (Object)(object)val3.ItemDrop == (Object)null) { Plugin.Log.LogError((object)"Impossibile clonare Battleaxe per Uruz Cleaver."); return; } SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_itemType = (ItemType)14; shared.m_skillType = (SkillType)7; shared.m_damages = new DamageTypes { m_slash = 24f, m_blunt = 4f }; shared.m_damagesPerLevel = new DamageTypes { m_slash = 3f, m_blunt = 1f }; shared.m_attackForce = 55f; shared.m_backstabBonus = 3f; shared.m_blockPower = 12f; shared.m_blockPowerPerLevel = 3f; shared.m_deflectionForce = 20f; shared.m_deflectionForcePerLevel = 5f; shared.m_timedBlockBonus = 2f; shared.m_maxQuality = 4; shared.m_useDurability = true; shared.m_maxDurability = 140f; shared.m_durabilityPerLevel = 45f; shared.m_movementModifier = -0.08f; if (shared.m_attack != null) { shared.m_attack = shared.m_attack.Clone(); shared.m_attack.m_attackStamina = 12f; } if (shared.m_secondaryAttack != null) { shared.m_secondaryAttack = shared.m_secondaryAttack.Clone(); shared.m_secondaryAttack.m_attackStamina = 18f; } NornsStaffModels.ReplaceVanillaVisual(val3.ItemPrefab, NornsStaffModels.Style.UruzCleaver); if (!ItemManager.Instance.AddItem(val3)) { Plugin.Log.LogError((object)"Jotunn ha rifiutato Uruz Cleaver."); return; } _created = true; Plugin.Log.LogInfo((object)"Uruz Cleaver iniziale registrata."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Registrazione di Uruz Cleaver fallita: {arg}"); } } private static Sprite LoadIcon(string fileName) { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { return null; } string text = Path.Combine(directoryName, "art", "items", fileName); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("Icona arma Berserker non trovata: " + text)); return null; } return AssetUtils.LoadSpriteFromFile(text); } } public sealed class BlackHoleVfxController : MonoBehaviour { public const float DefaultActiveDuration = 6f; public const float DefaultResidualDuration = 1.2f; public Transform GroundFieldGroup; public Transform GroundVortexGroup; public Transform GroundVortexCounterGroup; public Transform SingularityGroup; public Transform AccretionGroup; public Transform AccretionCounterGroup; public Transform GravityFlowGroup; public Light EffectLight; public float ActiveDuration = 6f; public float ResidualDuration = 1.2f; private Vector3 _groundFieldScale; private Quaternion _groundVortexRotation; private Quaternion _groundVortexCounterRotation; private Vector3 _singularityScale; private Vector3 _singularityPosition; private Vector3 _accretionScale; private Vector3 _counterScale; private Vector3 _gravityFlowScale; private Camera _camera; private float _startedAt; private bool _implosionPlayed; private void OnEnable() { //IL_001c: 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_0021: 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_0035: 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_0068: 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_006d: 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_0081: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unkn