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 ShockwaveGrenade v0.1.0
ShockwaveGrenade.dll
Decompiled 2 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering.HighDefinition; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShockwaveGrenade")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+31b5772e5e3f23ce0215b676606995a042f4e285")] [assembly: AssemblyProduct("ShockwaveGrenade")] [assembly: AssemblyTitle("ShockwaveGrenade")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ShockwaveGrenade { internal class Blast : MonoBehaviour { private const int RoomMask = 256; private const int EnemyMask = 524288; private const float RingTime = 0.4f; private Vector3 _from; private Vector3 _to; private float _t; private float _duration; private float _arc; private BlastParams _p; private PlayerControllerB _thrower; internal static Vector3 LastBlastPosition; internal static float LastBlastTime = -1f; public static void Fly(Vector3 from, Vector3 to, BlastParams p, PlayerControllerB thrower) { //IL_000d: 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) //IL_004f: 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_0058: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) GameObject val = (GameObject)(((Object)(object)Registry.ModelAsset != (Object)null) ? ((object)Object.Instantiate<GameObject>(Registry.ModelAsset)) : ((object)new GameObject())); ((Object)val).name = "ShockwaveProjectile"; Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } Blast blast = val.AddComponent<Blast>(); float num = Vector3.Distance(from, to); blast._from = from; blast._to = to; blast._p = p; blast._thrower = thrower; blast._duration = Mathf.Clamp(num / 14f, 0.2f, 1.1f); blast._arc = Mathf.Clamp(num * 0.12f, 0.1f, 1.5f); val.transform.position = from; PlayAt(Registry.ThrowClip, from, 0.8f, 20f); } private void Update() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime; float num = Mathf.Clamp01(_t / _duration); ((Component)this).transform.position = Vector3.Lerp(_from, _to, num) + Vector3.up * (_arc * 4f * num * (1f - num)); ((Component)this).transform.rotation = Quaternion.Euler(0f, _t * 720f, 0f); if (!(num < 1f)) { try { Explode(_to, _p, _thrower); } catch (Exception arg) { Plugin.Log.LogError((object)$"Shockwave: blast failed: {arg}"); } Object.Destroy((Object)(object)((Component)this).gameObject); } } internal static void Explode(Vector3 pos, BlastParams p, PlayerControllerB thrower) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0057: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) LastBlastPosition = pos; LastBlastTime = Time.time; PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; AudioSource val = PlayAt(Registry.BlastClip, pos, 1f, 60f); if ((Object)(object)val != (Object)null && (Object)(object)Registry.BlastClip != (Object)null) { WalkieTalkie.TransmitOneShotAudio(val, Registry.BlastClip, 0.9f); } SpawnRing(pos, p.Radius); if (p.Noise > 0f && (Object)(object)RoundManager.Instance != (Object)null) { RoundManager.Instance.PlayAudibleNoise(pos, p.Noise, 0.9f, 0, false, 0); } if (Plugin.ScreenShake.Value && (Object)(object)localPlayerController != (Object)null && (Object)(object)HUDManager.Instance != (Object)null && Vector3.Distance(((Component)localPlayerController).transform.position, pos) < 14f) { HUDManager.Instance.ShakeCamera((ScreenShakeType)0); } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val2 in allPlayerScripts) { if (InRange(val2, pos, p, thrower)) { PlayAt(Registry.WhooshClip, ((Component)val2).transform.position + Vector3.up, ((Object)(object)val2 == (Object)(object)localPlayerController) ? 0.6f : 0.8f, 25f); if ((Object)(object)val2 == (Object)(object)localPlayerController) { Launch(localPlayerController, pos, p); } } } if (p.Stun > 0f) { HashSet<EnemyAI> hashSet = new HashSet<EnemyAI>(); Collider[] array = Physics.OverlapSphere(pos, p.Radius, 524288); for (int i = 0; i < array.Length; i++) { EnemyAICollisionDetect component = ((Component)array[i]).GetComponent<EnemyAICollisionDetect>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.mainScript == (Object)null) && hashSet.Add(component.mainScript) && !Physics.Linecast(pos + Vector3.up * 0.5f, ((Component)component.mainScript).transform.position + Vector3.up * 0.5f, 256, (QueryTriggerInteraction)1)) { component.mainScript.SetEnemyStunned(true, p.Stun, thrower); } } } if (p.PushCruiser) { VehicleController val3 = Object.FindObjectOfType<VehicleController>(); if ((Object)(object)val3 != (Object)null && ((NetworkBehaviour)val3).IsOwner && !val3.magnetedToShip && (Object)(object)val3.mainRigidbody != (Object)null && Vector3.Distance(((Component)val3).transform.position, pos) < p.Radius * 2f) { val3.mainRigidbody.AddExplosionForce(p.Up * 50f, pos, p.Radius * 2f, 3f, (ForceMode)1); } } } private static bool InRange(PlayerControllerB pl, Vector3 pos, BlastParams p, PlayerControllerB thrower) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pl == (Object)null || !pl.isPlayerControlled || pl.isPlayerDead) { return false; } if (!p.LaunchOthers && (Object)(object)pl != (Object)(object)thrower) { return false; } if (pl.inVehicleAnimation || (Object)(object)pl.inAnimationWithEnemy != (Object)null) { return false; } if (StartOfRound.Instance.inShipPhase && pl.isInHangarShipRoom) { return false; } if (Vector3.Distance(((Component)pl).transform.position, pos) > p.Radius) { return false; } return !Physics.Linecast(pos + Vector3.up * 0.3f, ((Component)pl).transform.position + Vector3.up * 1f, 256, (QueryTriggerInteraction)1); } private static void Launch(PlayerControllerB me, Vector3 pos, BlastParams p) { //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_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_007b: 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_0052: 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_0080: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_0057: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)me).transform.position - pos; val.y = 0f; if (((Vector3)(ref val)).magnitude < 1.5f) { val = (((Object)(object)me.gameplayCamera != (Object)null) ? ((Component)me.gameplayCamera).transform.forward : ((Component)me).transform.forward); val.y = 0f; } val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.zero); FallGuard.Launch(me, Vector3.up * p.Up + val * p.Out, p.After, p.Max); } private static AudioSource PlayAt(AudioClip clip, Vector3 pos, float volume, float maxDistance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)clip == (Object)null) { return null; } GameObject val = new GameObject("ShockwaveSound"); val.transform.position = pos; AudioSource obj = val.AddComponent<AudioSource>(); obj.outputAudioMixerGroup = Registry.Mixer; obj.spatialBlend = 1f; obj.rolloffMode = (AudioRolloffMode)1; obj.minDistance = 2f; obj.maxDistance = maxDistance; obj.dopplerLevel = 0f; obj.PlayOneShot(clip, volume); Object.Destroy((Object)(object)val, clip.length + 0.5f); return obj; } private static void SpawnRing(Vector3 pos, float radius) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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_001c: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ShockwaveRingFx"); val.transform.position = pos + Vector3.up * 0.15f; if ((Object)(object)Registry.RingAsset != (Object)null) { Object.Instantiate<GameObject>(Registry.RingAsset, val.transform, false).transform.localPosition = Vector3.zero; } GameObject val2 = new GameObject("Flash"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector3.up * 0.5f; Light obj = val2.AddComponent<Light>(); obj.type = (LightType)2; obj.color = Registry.CoreColor; obj.shadows = (LightShadows)0; HDAdditionalLightData val3 = val2.AddComponent<HDAdditionalLightData>(); val3.SetColor(Registry.CoreColor, -1f); val3.EnableShadows(false); val3.SetRange(radius * 1.5f); val.AddComponent<RingFx>().Init(radius, 0.4f, val3); } } internal class RingFx : MonoBehaviour { private float _radius; private float _time; private float _t; private HDAdditionalLightData _light; private Renderer[] _renderers; private MaterialPropertyBlock _mpb; public void Init(float radius, float time, HDAdditionalLightData light) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown _radius = radius; _time = time; _light = light; _renderers = ((Component)this).GetComponentsInChildren<Renderer>(); _mpb = new MaterialPropertyBlock(); Apply(0f); } private void Update() { _t += Time.deltaTime; float u = Mathf.Clamp01(_t / _time); Apply(u); if (_t > _time + 0.1f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Apply(float u) { //IL_0053: 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_00aa: Unknown result type (might be due to invalid IL or missing references) float num = 1f - (1f - u) * (1f - u); ((Component)this).transform.localScale = new Vector3(Mathf.Max(0.05f, _radius * num), 1f + 2f * (1f - u), Mathf.Max(0.05f, _radius * num)); float num2 = 1f - u; Renderer[] renderers = _renderers; foreach (Renderer obj in renderers) { obj.GetPropertyBlock(_mpb); _mpb.SetColor("_UnlitColor", new Color(0.35f, 0.45f, 1f, 1f) * (num2 * 3f)); obj.SetPropertyBlock(_mpb); } if ((Object)(object)_light != (Object)null) { _light.SetIntensity(3000f * num2 * num2, (LightUnit)0); } } } [HarmonyPatch] internal static class FallGuard { private static float _launchTime = -100f; private static float _openUntil = -100f; private static float _afterLanding = 1f; private static bool _landed = true; internal static int Blocked; internal static bool IsOpen => Time.time < _openUntil; internal static void Reset() { _openUntil = -100f; _landed = true; } internal static void Launch(PlayerControllerB me, Vector3 impulse, float afterLanding, float maxSeconds) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_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_006e: Unknown result type (might be due to invalid IL or missing references) if (me.isClimbingLadder || me.inSpecialInteractAnimation) { me.CancelSpecialTriggerAnimations(); } me.ResetFallGravity(); me.externalForceAutoFade += impulse; _launchTime = Time.time; _openUntil = Time.time + Mathf.Max(0.5f, maxSeconds); _afterLanding = Mathf.Max(0f, afterLanding); _landed = false; Plugin.Log.LogInfo((object)$"Shockwave: launched with {impulse} (no fall damage for up to {maxSeconds:F0} s)."); } private static bool IsLocal(PlayerControllerB p) { if ((Object)(object)p != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null) { return (Object)(object)p == (Object)(object)GameNetworkManager.Instance.localPlayerController; } return false; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void AfterUpdate(PlayerControllerB __instance) { if (!_landed && IsLocal(__instance) && !(Time.time - _launchTime < 0.25f) && !((Object)(object)__instance.thisController == (Object)null) && __instance.thisController.isGrounded) { _landed = true; _openUntil = Mathf.Min(_openUntil, Time.time + _afterLanding); Plugin.Log.LogInfo((object)$"Shockwave: landed after {Time.time - _launchTime:F2} s."); } } [HarmonyPatch(typeof(PlayerControllerB), "PlayerHitGroundEffects")] [HarmonyPrefix] private static void BeforeHitGround(PlayerControllerB __instance) { if (IsOpen && IsLocal(__instance) && __instance.takingFallDamage) { __instance.takingFallDamage = false; Blocked++; Plugin.Log.LogInfo((object)$"Shockwave: fall damage blocked (fall speed {__instance.fallValueUncapped:F1})."); } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] [HarmonyPrefix] private static bool BeforeDamage(PlayerControllerB __instance, int damageNumber, CauseOfDeath causeOfDeath, bool fallDamage) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if (!IsOpen || !IsLocal(__instance)) { return true; } if ((int)causeOfDeath != 2 && !fallDamage) { return true; } Blocked++; Plugin.Log.LogInfo((object)$"Shockwave: {damageNumber} fall damage blocked."); return false; } } public class ShockwaveGrenadeItem : GrabbableObject { private const int ThrowMask = 268437761; private const float Cooldown = 0.75f; internal int Used; private float _lastThrow = -10f; private bool _gone; private Renderer[] _renderers; private MaterialPropertyBlock _mpb; internal int ChargesLeft => Mathf.Max(0, Net.Charges - Used); public override void Start() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown ((GrabbableObject)this).Start(); _renderers = ((Component)this).GetComponentsInChildren<Renderer>(true); _mpb = new MaterialPropertyBlock(); } public override int GetItemDataToSave() { return Used; } public override void LoadItemSaveData(int saveData) { Used = Mathf.Max(0, saveData); } public override void EquipItem() { ((GrabbableObject)this).EquipItem(); ((GrabbableObject)this).SetControlTipsForItem(); } public override void SetControlTipsForItem() { if (((NetworkBehaviour)this).IsOwner && !((Object)(object)base.playerHeldBy == (Object)null) && !((Object)(object)base.playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController)) { HUDManager.Instance.ChangeControlTipMultiple(new string[1] { $"Throw shockwave ({ChargesLeft} left) : [LMB]" }, true, base.itemProperties); } } public override void ItemActivate(bool used, bool buttonDown = true) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).ItemActivate(used, buttonDown); if (buttonDown && !_gone && !((Object)(object)base.playerHeldBy == (Object)null)) { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if (!((Object)(object)base.playerHeldBy != (Object)(object)localPlayerController) && !(Time.time - _lastThrow < 0.75f) && ChargesLeft > 0) { _lastThrow = Time.time; Transform transform = ((Component)base.playerHeldBy.gameplayCamera).transform; Vector3 val = transform.position + transform.forward * 0.6f - transform.up * 0.25f + transform.right * 0.2f; Vector3 val2 = ThrowDestination(transform); Plugin.Log.LogInfo((object)$"Shockwave: throw from {val} to {val2} ({ChargesLeft} left before this one)."); Net.RequestThrow(this, val, val2); } } } internal static Vector3 ThrowDestination(Transform cam) { //IL_0003: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Ray val = default(Ray); ((Ray)(ref val))..ctor(cam.position, cam.forward); RaycastHit val3 = default(RaycastHit); Vector3 val2 = (Physics.Raycast(val, ref val3, 12f, 268437761, (QueryTriggerInteraction)1) ? ((Ray)(ref val)).GetPoint(((RaycastHit)(ref val3)).distance - 0.05f) : ((Ray)(ref val)).GetPoint(10f)); Ray val4 = default(Ray); ((Ray)(ref val4))..ctor(val2, Vector3.down); if (!Physics.Raycast(val4, ref val3, 30f, 268437761, (QueryTriggerInteraction)1)) { return ((Ray)(ref val4)).GetPoint(30f); } return ((RaycastHit)(ref val3)).point + Vector3.up * 0.05f; } internal void OnThrown(int chargesLeft) { Used = Mathf.Max(0, Net.Charges - chargesLeft); PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; bool flag = (Object)(object)base.playerHeldBy != (Object)null && (Object)(object)base.playerHeldBy == (Object)(object)localPlayerController && base.isHeld; if (flag && chargesLeft > 0) { ((GrabbableObject)this).SetControlTipsForItem(); } if (chargesLeft > 0 || _gone) { return; } _gone = true; if (flag) { base.playerHeldBy.DespawnHeldObject(); HUDManager instance = HUDManager.Instance; if (instance != null) { instance.ClearControlTips(); } } else if (Net.IsHost && !base.isHeld && (Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned) { ((NetworkBehaviour)this).NetworkObject.Despawn(true); } } public override void LateUpdate() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).LateUpdate(); if (_renderers == null) { return; } float num = 4f * (0.7f + 0.3f * Mathf.Sin(Time.time * 4f)); Renderer[] renderers = _renderers; foreach (Renderer val in renderers) { if ((Object)(object)val == (Object)null) { continue; } Material[] sharedMaterials = val.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (!((Object)(object)sharedMaterials[j] == (Object)null) && ((Object)sharedMaterials[j]).name.StartsWith("M_Shock_Core")) { val.GetPropertyBlock(_mpb, j); _mpb.SetColor("_EmissiveColor", Registry.CoreColor * num); val.SetPropertyBlock(_mpb, j); } } } } } internal struct BlastParams { public float Up; public float Out; public float Radius; public float Stun; public float After; public float Max; public float Noise; public bool LaunchOthers; public bool PushCruiser; public static BlastParams FromConfig() { return new BlastParams { Up = Plugin.UpForce.Value, Out = Plugin.OutForce.Value, Radius = Plugin.BlastRadius.Value, Stun = Plugin.EnemyStunSeconds.Value, After = Plugin.NoFallDamageAfterLanding.Value, Max = Plugin.NoFallDamageMaxSeconds.Value, Noise = Plugin.NoiseRange.Value, LaunchOthers = Plugin.LaunchOthers.Value, PushCruiser = Plugin.PushCruiser.Value }; } public void Write(FastBufferWriter w) { //IL_000a: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0062: 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_0078: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Up, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Out, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Radius, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Stun, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref After, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Max, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Noise, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref LaunchOthers, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref PushCruiser, default(ForPrimitives)); } public static BlastParams Read(FastBufferReader r) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) BlastParams result = default(BlastParams); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Up, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Out, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Radius, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Stun, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.After, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Max, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Noise, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref result.LaunchOthers, default(ForPrimitives)); ((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref result.PushCruiser, default(ForPrimitives)); return result; } } internal static class Net { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnThrowRequest; public static HandleNamedMessageDelegate <1>__OnThrow; public static HandleNamedMessageDelegate <2>__OnConfig; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static HandleNamedMessageDelegate <>9__11_0; public static Func<ulong, bool> <>9__15_0; public static Action<FastBufferWriter> <>9__18_0; internal void <Register>b__11_0(ulong sender, FastBufferReader r) { SendConfig(sender); } internal bool <HostThrow>b__15_0(ulong c) { return c != 0; } internal void <SendConfig>b__18_0(FastBufferWriter w) { //IL_0011: 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_002e: 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) int value = Plugin.Price.Value; ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives)); value = Plugin.Charges.Value; ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives)); } } private const string MsgThrowRequest = "DanielLC.Shockwave.ThrowRequest"; private const string MsgThrow = "DanielLC.Shockwave.Throw"; private const string MsgConfigRequest = "DanielLC.Shockwave.ConfigRequest"; private const string MsgConfig = "DanielLC.Shockwave.Config"; private static readonly string[] All = new string[4] { "DanielLC.Shockwave.ThrowRequest", "DanielLC.Shockwave.Throw", "DanielLC.Shockwave.ConfigRequest", "DanielLC.Shockwave.Config" }; private static bool _registered; private static int? _hostCharges; public static bool IsHost { get { if ((Object)(object)NetworkManager.Singleton != (Object)null) { return NetworkManager.Singleton.IsServer; } return false; } } public static int Charges => Math.Max(1, _hostCharges ?? Plugin.Charges.Value); public static void Register() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //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_005a: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (_registered || (Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null) { return; } CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; _hostCharges = null; if (singleton.IsServer) { object obj = <>O.<0>__OnThrowRequest; if (obj == null) { HandleNamedMessageDelegate val = OnThrowRequest; <>O.<0>__OnThrowRequest = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.ThrowRequest", (HandleNamedMessageDelegate)obj); object obj2 = <>c.<>9__11_0; if (obj2 == null) { HandleNamedMessageDelegate val2 = delegate(ulong sender, FastBufferReader r) { SendConfig(sender); }; <>c.<>9__11_0 = val2; obj2 = (object)val2; } customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.ConfigRequest", (HandleNamedMessageDelegate)obj2); } else { object obj3 = <>O.<1>__OnThrow; if (obj3 == null) { HandleNamedMessageDelegate val3 = OnThrow; <>O.<1>__OnThrow = val3; obj3 = (object)val3; } customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.Throw", (HandleNamedMessageDelegate)obj3); object obj4 = <>O.<2>__OnConfig; if (obj4 == null) { HandleNamedMessageDelegate val4 = OnConfig; <>O.<2>__OnConfig = val4; obj4 = (object)val4; } customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.Config", (HandleNamedMessageDelegate)obj4); Send("DanielLC.Shockwave.ConfigRequest", 0uL, null); } _registered = true; } public static void Unregister() { CustomMessagingManager val = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.CustomMessagingManager : null); if (val != null) { string[] all = All; foreach (string text in all) { try { val.UnregisterNamedMessageHandler(text); } catch (Exception) { } } } _registered = false; _hostCharges = null; } public static void RequestThrow(ShockwaveGrenadeItem item, Vector3 from, Vector3 to) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (IsHost) { HostThrow(((NetworkBehaviour)item).NetworkObjectId, from, to, 0uL); return; } Send("DanielLC.Shockwave.ThrowRequest", 0uL, delegate(FastBufferWriter w) { //IL_0012: 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) ulong networkObjectId = ((NetworkBehaviour)item).NetworkObjectId; ((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives)); ((FastBufferWriter)(ref w)).WriteValueSafe(ref from); ((FastBufferWriter)(ref w)).WriteValueSafe(ref to); }); } private static void OnThrowRequest(ulong sender, FastBufferReader r) { //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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) ulong itemId = default(ulong); ((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref itemId, default(ForPrimitives)); Vector3 val = default(Vector3); ((FastBufferReader)(ref r)).ReadValueSafe(ref val); Vector3 to = default(Vector3); ((FastBufferReader)(ref r)).ReadValueSafe(ref to); HostThrow(itemId, val, to, sender); } private static void HostThrow(ulong itemId, Vector3 from, Vector3 to, ulong sender) { //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(itemId, out var value)) { return; } ShockwaveGrenadeItem component = ((Component)value).GetComponent<ShockwaveGrenadeItem>(); if ((Object)(object)component == (Object)null || component.ChargesLeft <= 0) { Plugin.Log.LogInfo((object)"Shockwave: throw refused (no charges)."); return; } if ((Object)(object)((GrabbableObject)component).playerHeldBy == (Object)null || ((GrabbableObject)component).playerHeldBy.actualClientId != sender) { Plugin.Log.LogInfo((object)"Shockwave: throw refused (sender isn't holding it)."); return; } int left = component.ChargesLeft - 1; BlastParams p = BlastParams.FromConfig(); ulong actualClientId = ((GrabbableObject)component).playerHeldBy.actualClientId; List<ulong> list = singleton.ConnectedClientsIds.Where((ulong c) => c != 0).ToList(); if (list.Count > 0) { FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, 1024); try { ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref itemId, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe(ref from); ((FastBufferWriter)(ref val)).WriteValueSafe(ref to); ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref left, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref actualClientId, default(ForPrimitives)); p.Write(val); singleton.CustomMessagingManager.SendNamedMessage("DanielLC.Shockwave.Throw", (IReadOnlyList<ulong>)list, val, (NetworkDelivery)3); } finally { ((FastBufferWriter)(ref val)).Dispose(); } } ApplyThrow(itemId, from, to, left, actualClientId, p); } private static void OnThrow(ulong sender, FastBufferReader r) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0055: Unknown result type (might be due to invalid IL or missing references) ulong itemId = default(ulong); ((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref itemId, default(ForPrimitives)); Vector3 val = default(Vector3); ((FastBufferReader)(ref r)).ReadValueSafe(ref val); Vector3 to = default(Vector3); ((FastBufferReader)(ref r)).ReadValueSafe(ref to); int left = default(int); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref left, default(ForPrimitives)); ulong throwerClient = default(ulong); ((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref throwerClient, default(ForPrimitives)); BlastParams p = BlastParams.Read(r); ApplyThrow(itemId, val, to, left, throwerClient, p); } private static void ApplyThrow(ulong itemId, Vector3 from, Vector3 to, int left, ulong throwerClient, BlastParams p) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB thrower = StartOfRound.Instance?.allPlayerScripts?.FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => (Object)(object)x != (Object)null && x.actualClientId == throwerClient && x.isPlayerControlled)); Blast.Fly(from, to, p, thrower); NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null && singleton.SpawnManager.SpawnedObjects.TryGetValue(itemId, out var value)) { ((Component)value).GetComponent<ShockwaveGrenadeItem>()?.OnThrown(left); } } private static void SendConfig(ulong client) { Send("DanielLC.Shockwave.Config", client, delegate(FastBufferWriter w) { //IL_0011: 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_002e: 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) int value = Plugin.Price.Value; ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives)); value = Plugin.Charges.Value; ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives)); }); } private static void OnConfig(ulong sender, FastBufferReader r) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) int num = default(int); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num, default(ForPrimitives)); int num2 = default(int); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num2, default(ForPrimitives)); _hostCharges = num2; Registry.ApplyPrice(num); Plugin.Log.LogInfo((object)$"Shockwave: host settings: price {num}, {num2} charges."); } private static void Send(string name, ulong to, Action<FastBufferWriter> write) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, 1024); try { write?.Invoke(val); singleton.CustomMessagingManager.SendNamedMessage(name, to, val, (NetworkDelivery)3); } finally { ((FastBufferWriter)(ref val)).Dispose(); } } } [HarmonyPatch] internal static class NetPatches { [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void StartOfRoundStart() { Net.Register(); if (Net.IsHost) { Registry.ApplyPrice(Plugin.Price.Value); } } [HarmonyPatch(typeof(StartOfRound), "OnDestroy")] [HarmonyPrefix] private static void StartOfRoundDestroy() { Net.Unregister(); FallGuard.Reset(); } } public static class PluginInfo { public const string Guid = "daniel.lethalcompany.shockwavegrenade"; public const string Name = "Shockwave Grenade"; public const string Version = "0.1.0"; } [BepInPlugin("daniel.lethalcompany.shockwavegrenade", "Shockwave Grenade", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<int> Price; internal static ConfigEntry<int> Charges; internal static ConfigEntry<bool> LaunchOthers; internal static ConfigEntry<float> BlastRadius; internal static ConfigEntry<float> UpForce; internal static ConfigEntry<float> OutForce; internal static ConfigEntry<float> EnemyStunSeconds; internal static ConfigEntry<float> NoFallDamageAfterLanding; internal static ConfigEntry<float> NoFallDamageMaxSeconds; internal static ConfigEntry<bool> PushCruiser; internal static ConfigEntry<float> NoiseRange; internal static ConfigEntry<bool> ScreenShake; private readonly Harmony _harmony = new Harmony("daniel.lethalcompany.shockwavegrenade"); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Price = ((BaseUnityPlugin)this).Config.Bind<int>("Store (host)", "Price", 120, "Store price in credits (Daniel, q_9b6b2aa2babd49ba)."); Charges = ((BaseUnityPlugin)this).Config.Bind<int>("Store (host)", "Charges", 3, "Throws per grenade. It stays in your hand until the last one."); LaunchOthers = ((BaseUnityPlugin)this).Config.Bind<bool>("Shockwave (host)", "Launch other players", true, "Launch every player in range, not only the thrower."); BlastRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Blast radius", 6f, "Metres."); UpForce = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Up force", 50f, "Upward push. 50 is about 8 m high on open ground."); OutForce = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Out force", 20f, "Push away from the blast. 20 is about 8-9 m sideways."); EnemyStunSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Enemy stun seconds", 1.5f, "Stun enemies in range for this long (0 = off). Enemies are never moved."); NoFallDamageAfterLanding = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "No fall damage after landing", 1f, "Seconds of fall-damage protection left after your first landing."); NoFallDamageMaxSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "No fall damage max seconds", 10f, "The protection never lasts longer than this after a launch."); PushCruiser = ((BaseUnityPlugin)this).Config.Bind<bool>("Shockwave (host)", "Push Cruiser", false, "Push the Company Cruiser too (like a landmine does)."); NoiseRange = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Noise range", 15f, "Monsters within this range hear the blast."); ScreenShake = ((BaseUnityPlugin)this).Config.Bind<bool>("Local", "Screen shake", true, "Shake your camera a little when a blast goes off near you."); _harmony.PatchAll(typeof(Plugin).Assembly); Registry.Load(); Log.LogInfo((object)"Shockwave Grenade 0.1.0 loaded."); } } internal static class Registry { private static readonly string[] Templates = new string[3] { "Stun grenade", "Easter egg", "Whoopie cushion" }; internal static readonly Color CoreColor = new Color(0.3f, 0.4f, 1f); internal const float CoreGlow = 4f; internal const float LightLumen = 40f; internal const float LightRange = 2f; internal static readonly Vector3 HoldPosition = new Vector3(0f, 0.075f, 0.01f); internal static readonly Vector3 HoldRotation; private static GameObject _container; private static bool _shopRegistered; internal static GameObject ModelAsset { get; private set; } internal static GameObject RingAsset { get; private set; } internal static AudioClip BlastClip { get; private set; } internal static AudioClip WhooshClip { get; private set; } internal static AudioClip ThrowClip { get; private set; } internal static AudioMixerGroup Mixer { get; private set; } public static GameObject Prefab { get; private set; } public static Item Item { get; private set; } public static void Load() { try { using (Stream stream = Res("shockwave_grenade")) { AssetBundle val = ((stream != null) ? AssetBundle.LoadFromStream(stream) : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Shockwave: the embedded bundle is missing."); return; } ModelAsset = val.LoadAsset<GameObject>("ShockwaveGrenadeModel"); RingAsset = val.LoadAsset<GameObject>("ShockwaveRing"); } BlastClip = Wav.Load(Res("blast.wav"), "ShockwaveBlast"); WhooshClip = Wav.Load(Res("whoosh.wav"), "ShockwaveWhoosh"); ThrowClip = Wav.Load(Res("throw.wav"), "ShockwaveThrow"); Plugin.Log.LogInfo((object)($"Shockwave: assets loaded (model {(Object)(object)ModelAsset != (Object)null}, ring {(Object)(object)RingAsset != (Object)null}, " + $"sounds {(Object)(object)BlastClip != (Object)null}/{(Object)(object)WhooshClip != (Object)null}/{(Object)(object)ThrowClip != (Object)null}).")); } catch (Exception arg) { Plugin.Log.LogError((object)$"Shockwave: assets failed to load: {arg}"); } } private static Stream Res(string name) { return Assembly.GetExecutingAssembly().GetManifestResourceStream("ShockwaveGrenade." + name); } internal static void BuildPrefab() { //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Invalid comparison between Unknown and I4 //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Prefab != (Object)null) { return; } if ((Object)(object)ModelAsset == (Object)null) { Plugin.Log.LogError((object)"Shockwave: no model, so no item."); return; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { Plugin.Log.LogError((object)"Shockwave: no NetworkManager at GameNetworkManager.Start."); return; } List<GrabbableObject> candidates = (from p in singleton.NetworkConfig.Prefabs.Prefabs select (!((Object)(object)p.Prefab != (Object)null)) ? null : p.Prefab.GetComponent<GrabbableObject>() into g where (Object)(object)g != (Object)null && (Object)(object)g.itemProperties != (Object)null select g).ToList(); GrabbableObject val = Templates.Select((string n) => ((IEnumerable<GrabbableObject>)candidates).FirstOrDefault((Func<GrabbableObject, bool>)((GrabbableObject g) => g.itemProperties.itemName == n))).FirstOrDefault<GrabbableObject>((Func<GrabbableObject, bool>)((GrabbableObject g) => (Object)(object)g != (Object)null)) ?? ((IEnumerable<GrabbableObject>)candidates).FirstOrDefault((Func<GrabbableObject, bool>)((GrabbableObject g) => !g.itemProperties.twoHanded)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Shockwave: no vanilla item to base the grenade on."); return; } _container = new GameObject("ShockwaveGrenade.Prefabs"); _container.SetActive(false); ((Object)_container).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)_container); GameObject val2 = new GameObject("ShockwaveGrenade"); val2.transform.SetParent(_container.transform, false); val2.layer = ((Component)val).gameObject.layer; val2.tag = ((Component)val).gameObject.tag; NetworkObject obj = val2.AddComponent<NetworkObject>(); AccessTools.Field(typeof(NetworkObject), "GlobalObjectIdHash").SetValue(obj, StableHash("daniel.lethalcompany.shockwavegrenade.ShockwaveGrenade")); AudioSource component = ((Component)val).GetComponent<AudioSource>(); AudioSource val3 = val2.AddComponent<AudioSource>(); val3.playOnAwake = false; if ((Object)(object)component != (Object)null) { Mixer = component.outputAudioMixerGroup; val3.outputAudioMixerGroup = component.outputAudioMixerGroup; val3.spatialBlend = component.spatialBlend; val3.rolloffMode = component.rolloffMode; val3.minDistance = component.minDistance; val3.maxDistance = component.maxDistance; val3.dopplerLevel = component.dopplerLevel; val3.volume = component.volume; if ((int)component.rolloffMode == 2) { val3.SetCustomCurve((AudioSourceCurveType)0, component.GetCustomCurve((AudioSourceCurveType)0)); } } GameObject val4 = Object.Instantiate<GameObject>(ModelAsset, val2.transform, false); ((Object)val4).name = "Model"; val4.transform.localPosition = Vector3.zero; Transform[] componentsInChildren = val4.GetComponentsInChildren<Transform>(true); for (int num = 0; num < componentsInChildren.Length; num++) { ((Component)componentsInChildren[num]).gameObject.layer = val2.layer; } BoxCollider obj2 = val2.AddComponent<BoxCollider>(); obj2.center = Vector3.zero; obj2.size = new Vector3(0.16f, 0.16f, 0.16f); ((Collider)obj2).isTrigger = (Object)(object)((Component)val).GetComponent<Collider>() != (Object)null && ((Component)val).GetComponent<Collider>().isTrigger; ScanNodeProperties componentInChildren = ((Component)val).GetComponentInChildren<ScanNodeProperties>(true); if ((Object)(object)componentInChildren != (Object)null) { ScanNodeProperties component2 = Object.Instantiate<GameObject>(((Component)componentInChildren).gameObject, val2.transform, false).GetComponent<ScanNodeProperties>(); ((Component)component2).transform.localPosition = Vector3.zero; component2.headerText = "Shockwave grenade"; component2.subText = "Launches the crew. No fall damage."; component2.scrapValue = 0; component2.nodeType = 0; } Item itemProperties = val.itemProperties; Item = Object.Instantiate<Item>(itemProperties); ((Object)Item).name = "ShockwaveGrenadeItem"; Item.itemName = "Shockwave grenade"; Item.spawnPrefab = val2; Item.isScrap = false; Item.minValue = (Item.maxValue = 0); Item.creditsWorth = Plugin.Price.Value; Item.highestSalePercentage = 80; Item.twoHanded = false; Item.requiresBattery = false; Item.isConductiveMetal = false; Item.isDefensiveWeapon = false; Item.holdButtonUse = false; Item.syncUseFunction = false; Item.saveItemVariable = true; Item.canBeGrabbedBeforeGameStart = true; Item.itemIsTrigger = false; Item.automaticallySetUsingPower = false; Item.meshVariants = (Mesh[])(object)new Mesh[0]; Item.materialVariants = (Material[])(object)new Material[0]; Item.spawnPositionTypes = new List<ItemGroup>(); Item.toolTips = new string[1] { "Throw shockwave : [LMB]" }; Item.verticalOffset = 0.065f; Item.restingRotation = Vector3.zero; Item.positionOffset = HoldPosition; Item.rotationOffset = HoldRotation; Item.weight = Mathf.Clamp(itemProperties.weight, 1f, 3.75f); ShockwaveGrenadeItem shockwaveGrenadeItem = val2.AddComponent<ShockwaveGrenadeItem>(); ((GrabbableObject)shockwaveGrenadeItem).itemProperties = Item; ((GrabbableObject)shockwaveGrenadeItem).grabbable = true; ((GrabbableObject)shockwaveGrenadeItem).grabbableToEnemies = true; ((GrabbableObject)shockwaveGrenadeItem).isInFactory = false; ((GrabbableObject)shockwaveGrenadeItem).scrapValue = 0; ((GrabbableObject)shockwaveGrenadeItem).mainObjectRenderer = val4.GetComponentInChildren<MeshRenderer>(); AddGlow(val4); Prefab = val2; singleton.AddNetworkPrefab(val2); RegisterWithLethalLib(); Plugin.Log.LogInfo((object)$"Shockwave: item built from \"{itemProperties.itemName}\" (hold anim {Item.grabAnim}, weight {Item.weight:F2})."); } private static void RegisterWithLethalLib() { if (!_shopRegistered) { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = "ShockwaveGrenadeInfo"; val.clearPreviousText = true; val.displayText = "SHOCKWAVE GRENADE\n\nThrow it [LMB] and it goes off where it lands, launching everyone within 6 m high into the air and away from the blast. Nobody takes fall damage until they land. Nearby monsters are stunned for a moment, but they hear it.\n\n3 throws per grenade. It won't save you from a bottomless pit.\n\n"; Items.RegisterShopItem(Item, (TerminalNode)null, (TerminalNode)null, val, Plugin.Price.Value); _shopRegistered = true; } } internal static void ApplyPrice(int price) { if ((Object)(object)Item == (Object)null || price <= 0) { return; } Item.creditsWorth = price; Terminal val = Object.FindObjectOfType<Terminal>(); if (val?.buyableItemsList == null) { return; } Item[] buyableItemsList = val.buyableItemsList; foreach (Item val2 in buyableItemsList) { if ((Object)(object)val2 != (Object)null && val2.itemName == Item.itemName) { val2.creditsWorth = price; } } } private static void AddGlow(GameObject model) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Glow"); val.transform.SetParent(model.transform, false); val.transform.localPosition = new Vector3(0f, 0.05f, 0f); val.layer = model.layer; Light obj = val.AddComponent<Light>(); obj.type = (LightType)2; obj.color = CoreColor; obj.range = 2f; obj.shadows = (LightShadows)0; HDAdditionalLightData obj2 = val.AddComponent<HDAdditionalLightData>(); obj2.SetIntensity(40f, (LightUnit)0); obj2.SetRange(2f); obj2.SetColor(CoreColor, -1f); obj2.EnableShadows(false); } private static uint StableHash(string s) { using MD5 mD = MD5.Create(); return BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes(s)), 0); } static Registry() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) Quaternion val = Quaternion.FromToRotation(Vector3.up, new Vector3(0.13f, -0.84f, -0.54f)); HoldRotation = ((Quaternion)(ref val)).eulerAngles; } } internal static class Wav { public static AudioClip Load(Stream s, string name) { if (s == null) { Plugin.Log.LogError((object)("Shockwave: sound " + name + " is missing.")); return null; } using (s) { using BinaryReader binaryReader = new BinaryReader(s); binaryReader.ReadBytes(12); int num = 1; int num2 = 44100; int num3 = 16; byte[] array = null; while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length - 8) { string text = Encoding.ASCII.GetString(binaryReader.ReadBytes(4)); int num4 = binaryReader.ReadInt32(); if (text == "fmt ") { binaryReader.ReadInt16(); num = binaryReader.ReadInt16(); num2 = binaryReader.ReadInt32(); binaryReader.ReadInt32(); binaryReader.ReadInt16(); num3 = binaryReader.ReadInt16(); if (num4 > 16) { binaryReader.ReadBytes(num4 - 16); } } else { if (text == "data") { array = binaryReader.ReadBytes(num4); break; } binaryReader.ReadBytes(num4); } } if (array == null || num3 != 16) { Plugin.Log.LogError((object)("Shockwave: sound " + name + " isn't 16-bit PCM.")); return null; } int num5 = array.Length / 2; float[] array2 = new float[num5]; for (int i = 0; i < num5; i++) { array2[i] = (float)BitConverter.ToInt16(array, i * 2) / 32768f; } AudioClip obj = AudioClip.Create(name, num5 / num, num, num2, false); obj.SetData(array2, 0); return obj; } } } [HarmonyPatch] internal static class RegistryPatches { [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void GameNetworkManagerStart() { Build("GameNetworkManager.Start"); } [HarmonyPatch(typeof(MenuManager), "Start")] [HarmonyPostfix] private static void MenuManagerStart() { Build("MenuManager.Start"); } private static void Build(string from) { if ((Object)(object)Registry.Prefab != (Object)null) { return; } Plugin.Log.LogInfo((object)("Shockwave: building the item (" + from + ").")); try { Registry.BuildPrefab(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Shockwave: building the item failed: {arg}"); } } } }