Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of EngineerGaussShotgun v0.3.0
BepInEx/plugins/EngiAlternateSkills.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using EntityStates; using Microsoft.CodeAnalysis; using On.RoR2; using R2API; using R2API.Utils; using RoR2; using RoR2.Skills; using RoR2.UI; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EngiAlternateSkills")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+27393ff00ec0c7866d1a398d7c63ef9cb2e620e4")] [assembly: AssemblyProduct("EngiAlternateSkills")] [assembly: AssemblyTitle("EngiAlternateSkills")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace EngiGaussShotgun { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.example.EngiGaussShotgun", "Engineer Gauss Shotgun", "1.0.0")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class EngiGaussShotgunPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <DeferredSurvivorBankLoad>d__46 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public EngiGaussShotgunPlugin <>4__this; private uint <commandoEventId>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DeferredSurvivorBankLoad>d__46(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0046; case 1: <>1__state = -1; goto IL_0046; case 2: { <>1__state = -1; <commandoEventId>5__1 = AkSoundEngine.GetIDFromString("Play_commando_R"); ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[GaussShotgun] Commando bank loaded - Play_commando_R ID: {<commandoEventId>5__1}"); return false; } IL_0046: if ((Object)(object)Stage.instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[GaussShotgun] Stage loaded, forcing Commando soundbank load..."); AkBankManager.LoadBank("char_Commando", true, true); <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadRequiredPrefabs>d__52 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public EngiGaussShotgunPlugin <>4__this; private string[] <>s__1; private int <>s__2; private string <prefabPath>5__3; private AsyncOperationHandle<GameObject> <loadOp>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadRequiredPrefabs>d__52(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) <>s__1 = null; <prefabPath>5__3 = null; <loadOp>5__4 = default(AsyncOperationHandle<GameObject>); <>1__state = -2; } private bool MoveNext() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>s__1 = requiredPrefabs; <>s__2 = 0; goto IL_010b; case 1: <>1__state = -1; if ((Object)(object)<loadOp>5__4.Result == (Object)null) { ((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)("[GaussShotgun] Failed to load required prefab: " + <prefabPath>5__3)); } else { ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("[GaussShotgun] Loaded prefab: " + <prefabPath>5__3)); } <loadOp>5__4 = default(AsyncOperationHandle<GameObject>); <prefabPath>5__3 = null; <>s__2++; goto IL_010b; case 2: { <>1__state = -1; return false; } IL_010b: if (<>s__2 < <>s__1.Length) { <prefabPath>5__3 = <>s__1[<>s__2]; <loadOp>5__4 = Addressables.LoadAssetAsync<GameObject>((object)<prefabPath>5__3); <>2__current = <loadOp>5__4; <>1__state = 1; return true; } <>s__1 = null; <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <VerifyBanksNextFrame>d__54 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string context; public EngiGaussShotgunPlugin <>4__this; private uint <idCommandoR>5__1; private uint <idBanditM1>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <VerifyBanksNextFrame>d__54(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <idCommandoR>5__1 = AkSoundEngine.GetIDFromString("Play_commando_R"); <idBanditM1>5__2 = AkSoundEngine.GetIDFromString("Play_bandit_M1_shot"); if (BankDebugEnabled) { ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[GaussShotgun] VerifyBanks ({context}): Play_commando_R={<idCommandoR>5__1} Play_bandit_M1_shot={<idBanditM1>5__2}"); } if (<idCommandoR>5__1 != 0 && <idBanditM1>5__2 != 0) { banksVerified = true; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static AssetBundle? assetBundle = null; private ConfigEntry<int>? stockConfig; private ConfigEntry<float>? damageConfig; private ConfigEntry<float>? reloadTimeConfig; private ConfigEntry<bool>? debugAllPelletImpactSoundConfig; private ConfigEntry<string>? reloadStartSoundConfig; private ConfigEntry<string>? reloadPerRoundSoundConfig; private ConfigEntry<bool>? reloadPlayPerRoundSoundConfig; private ConfigEntry<bool>? bankDebugConfig; private ConfigEntry<bool>? forceSurvivorBanksConfig; private static bool BankDebugEnabled; private static bool banksVerified; private static bool ForceSurvivorBanks; private static readonly Color GaussGreenColor = new Color(0.682f, 1f, 0.663f, 1f); private static Texture? gaussRampTexture; public static SkillDef? gaussShotgunSkillDef; private Sprite? gaussShotgunIcon; private static GameObject? customCrosshairPrefab; private static readonly string[] survivorBanks = new string[2] { "char_Commando", "char_bandit2" }; private static readonly string[] requiredPrefabs = new string[2] { "RoR2/Base/Bandit2/Bandit2Body.prefab", "RoR2/Base/Commando/CommandoBody.prefab" }; public static PluginInfo? PInfo { get; private set; } public static bool DebugAllPelletImpactSound { get; private set; } public static float ReloadPerRoundBaseTime { get; private set; } public static string ReloadStartSoundEvent { get; private set; } = "Play_engi_M1_chargeStock"; public static string ReloadPerRoundSoundEvent { get; private set; } = "Play_item_use_fireballDashRecharge"; public static bool ReloadPerRoundSoundEnabled { get; private set; } = true; private void Awake() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown PInfo = ((BaseUnityPlugin)this).Info; LoadConfig(); LoadAssets(); ((MonoBehaviour)this).StartCoroutine(DeferredSurvivorBankLoad()); Stage.onStageStartGlobal += OnStageStartGlobal; GenericSkill.SetSkillOverride += new hook_SetSkillOverride(GenericSkill_SetSkillOverride); SetupGaussShotgun(); SetupCustomCrosshair(); CreateCustomEffects(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Engineer Gauss Shotgun loaded successfully!"); } private void LoadConfig() { stockConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Gauss Shotgun", "Max Stock", 8, "Maximum ammo capacity for Gauss Shotgun"); damageConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Gauss Shotgun", "Damage Per Pellet", 0.6f, "Damage coefficient per pellet (fires 8 pellets total)"); reloadTimeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Gauss Shotgun", "Reload Time", 3f, "Time to reload one shot"); debugAllPelletImpactSoundConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Play Impact Sound Every Pellet", false, "If true, plays the impact event for every pellet hit instead of only first per shot."); reloadStartSoundConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Audio", "Reload Start Sound", "Play_engi_M1_chargeStock", "Sound event played when reload sequence begins."); reloadPerRoundSoundConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Audio", "Reload Per Round Sound", "Play_item_use_fireballDashRecharge", "Short subtle tick sound for each round added asynchronously."); reloadPlayPerRoundSoundConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "Enable Per Round Reload Sound", true, "Enable/disable per-round tick sound."); bankDebugConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableBankDebug", true, "If true, logs one-time resolution of cross-survivor weapon events."); forceSurvivorBanksConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "ForceLoadSurvivorBanks", true, "Force load Commando/Bandit survivor soundbanks so their events (e.g. Play_commando_R) are always available even if that survivor is not present."); SyncStaticDebugFlags(); debugAllPelletImpactSoundConfig.SettingChanged += delegate { SyncStaticDebugFlags(); }; } private void SyncStaticDebugFlags() { DebugAllPelletImpactSound = debugAllPelletImpactSoundConfig?.Value ?? false; ReloadPerRoundBaseTime = reloadTimeConfig?.Value ?? 3f; ReloadStartSoundEvent = reloadStartSoundConfig?.Value ?? ReloadStartSoundEvent; ReloadPerRoundSoundEvent = reloadPerRoundSoundConfig?.Value ?? ReloadPerRoundSoundEvent; ReloadPerRoundSoundEnabled = reloadPlayPerRoundSoundConfig?.Value ?? ReloadPerRoundSoundEnabled; BankDebugEnabled = bankDebugConfig.Value; ForceSurvivorBanks = forceSurvivorBanksConfig.Value; } private void LoadAssets() { //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_017d: 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_01ca: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) try { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); assetBundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "engineerassets")); if ((Object)(object)assetBundle == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load engineer asset bundle; custom visuals will be missing."); return; } gaussShotgunIcon = assetBundle.LoadAsset<Sprite>("GaussShotgun"); if ((Object)(object)gaussShotgunIcon == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"GaussShotgun sprite missing from bundle; using default cyan fallback."); Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array = (Color32[])(object)new Color32[4096]; for (int i = 0; i < array.Length; i++) { array[i] = new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue); } val.SetPixels32(array); val.Apply(); gaussShotgunIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error loading assets: " + ex.Message)); Texture2D val2 = new Texture2D(64, 64, (TextureFormat)4, false); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int j = 0; j < array2.Length; j++) { array2[j] = new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue); } val2.SetPixels32(array2); val2.Apply(); gaussShotgunIcon = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f); } } [IteratorStateMachine(typeof(<DeferredSurvivorBankLoad>d__46))] private IEnumerator DeferredSurvivorBankLoad() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DeferredSurvivorBankLoad>d__46(0) { <>4__this = this }; } private void OnStageStartGlobal(Stage stage) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[GaussShotgun] Stage " + ((Object)stage).name + " started, loading Commando soundbank...")); AkBankManager.LoadBank("char_Commando", true, true); uint iDFromString = AkSoundEngine.GetIDFromString("Play_commando_R"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[GaussShotgun] Commando bank status - Play_commando_R ID: {iDFromString}"); } private void CreateCustomEffects() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_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_002a: 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_00bc: 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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) if (GaussShotgunFire.customEffectsCreated) { return; } try { Texture val = gaussRampTexture; if ((Object)(object)val == (Object)null) { val = (gaussRampTexture = Addressables.LoadAssetAsync<Texture>((object)"RoR2/Base/Common/ColorRamps/texRampEngi.png").WaitForCompletion()); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"[GaussShotgun] Failed to load texRampEngi texture; custom effects will keep default remap."); } } GameObject val2 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/Muzzleflash1.prefab").WaitForCompletion(); GameObject val3 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Commando/HitsparkCommando.prefab").WaitForCompletion(); if ((Object)(object)val2 != (Object)null) { GaussShotgunFire.customMuzzleEffectPrefab = PrefabAPI.InstantiateClone(val2, "EngiGaussMuzzleFlash", false); GaussShotgunFire.customMuzzleEffectPrefab.SetActive(false); ApplyGaussVisualTheme(GaussShotgunFire.customMuzzleEffectPrefab, val, GaussGreenColor, tintLights: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[GaussShotgun] Applied gauss green tint to muzzle flash."); EffectComponent val4 = GaussShotgunFire.customMuzzleEffectPrefab.GetComponent<EffectComponent>(); if ((Object)(object)val4 == (Object)null) { val4 = GaussShotgunFire.customMuzzleEffectPrefab.AddComponent<EffectComponent>(); val4.applyScale = true; val4.parentToReferencedTransform = false; val4.positionAtReferencedTransform = true; val4.soundName = ""; } val4.effectIndex = (EffectIndex)(-1); VFXAttributes component = GaussShotgunFire.customMuzzleEffectPrefab.GetComponent<VFXAttributes>(); if ((Object)(object)component == (Object)null) { component = GaussShotgunFire.customMuzzleEffectPrefab.AddComponent<VFXAttributes>(); component.vfxIntensity = (VFXIntensity)0; component.vfxPriority = (VFXPriority)0; } ContentAddition.AddEffect(GaussShotgunFire.customMuzzleEffectPrefab); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[GaussShotgun] Custom muzzle flash registered with game"); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"[GaussShotgun] Failed to load base muzzle flash prefab"); } if ((Object)(object)val3 != (Object)null) { GaussShotgunFire.customHitEffectPrefab = PrefabAPI.InstantiateClone(val3, "EngiGaussHitSpark", false); GaussShotgunFire.customHitEffectPrefab.SetActive(false); ApplyGaussVisualTheme(GaussShotgunFire.customHitEffectPrefab, val, GaussGreenColor, tintLights: false); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[GaussShotgun] Applied gauss green tint to hit spark."); EffectComponent val5 = GaussShotgunFire.customHitEffectPrefab.GetComponent<EffectComponent>(); if ((Object)(object)val5 == (Object)null) { val5 = GaussShotgunFire.customHitEffectPrefab.AddComponent<EffectComponent>(); val5.applyScale = false; val5.parentToReferencedTransform = false; val5.positionAtReferencedTransform = true; val5.soundName = ""; } val5.effectIndex = (EffectIndex)(-1); VFXAttributes component2 = GaussShotgunFire.customHitEffectPrefab.GetComponent<VFXAttributes>(); if ((Object)(object)component2 == (Object)null) { component2 = GaussShotgunFire.customHitEffectPrefab.AddComponent<VFXAttributes>(); component2.vfxIntensity = (VFXIntensity)0; component2.vfxPriority = (VFXPriority)0; } ContentAddition.AddEffect(GaussShotgunFire.customHitEffectPrefab); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[GaussShotgun] Custom hit spark registered with game"); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"[GaussShotgun] Failed to load base hit spark prefab"); } GaussShotgunFire.customEffectsCreated = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[GaussShotgun] ===== Custom green effects creation complete ====="); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[GaussShotgun] Failed to create custom effects: " + ex.Message + "\n" + ex.StackTrace)); } } private static void ApplyGaussVisualTheme(GameObject effectRoot, Texture? rampTexture, Color tintColor, bool tintLights) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0243: 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_015b: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Expected O, but got Unknown //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)effectRoot)) { return; } if (tintLights) { Light[] componentsInChildren = effectRoot.GetComponentsInChildren<Light>(true); foreach (Light val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.color = tintColor; } } } Renderer[] componentsInChildren2 = effectRoot.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren2) { if ((Object)(object)val2 == (Object)null) { continue; } Material[] sharedMaterials = val2.sharedMaterials; bool flag = false; for (int k = 0; k < sharedMaterials.Length; k++) { Material val3 = sharedMaterials[k]; if ((Object)(object)val3 == (Object)null) { continue; } Material val4 = new Material(val3) { name = (((Object)val3).name.EndsWith("_GaussClone", StringComparison.Ordinal) ? ((Object)val3).name : (((Object)val3).name + "_GaussClone")) }; if ((Object)(object)rampTexture != (Object)null) { if (val4.HasProperty("_RemapTex")) { val4.SetTexture("_RemapTex", rampTexture); } if (val4.HasProperty("_Remap")) { val4.SetTexture("_Remap", rampTexture); } } if (val4.HasProperty("_TintColor")) { Color color = val4.GetColor("_TintColor"); val4.SetColor("_TintColor", new Color(tintColor.r, tintColor.g, tintColor.b, color.a)); } if (val4.HasProperty("_Color")) { Color color2 = val4.GetColor("_Color"); val4.SetColor("_Color", new Color(tintColor.r, tintColor.g, tintColor.b, color2.a)); } sharedMaterials[k] = val4; flag = true; } if (flag) { val2.sharedMaterials = sharedMaterials; } ParticleSystemRenderer val5 = (ParticleSystemRenderer)(object)((val2 is ParticleSystemRenderer) ? val2 : null); if (val5 == null || !((Object)(object)val5.trailMaterial != (Object)null)) { continue; } Material trailMaterial = val5.trailMaterial; Material val6 = new Material(trailMaterial) { name = (((Object)trailMaterial).name.EndsWith("_GaussClone", StringComparison.Ordinal) ? ((Object)trailMaterial).name : (((Object)trailMaterial).name + "_GaussClone")) }; if ((Object)(object)rampTexture != (Object)null) { if (val6.HasProperty("_RemapTex")) { val6.SetTexture("_RemapTex", rampTexture); } if (val6.HasProperty("_Remap")) { val6.SetTexture("_Remap", rampTexture); } } if (val6.HasProperty("_TintColor")) { Color color3 = val6.GetColor("_TintColor"); val6.SetColor("_TintColor", new Color(tintColor.r, tintColor.g, tintColor.b, color3.a)); } if (val6.HasProperty("_Color")) { Color color4 = val6.GetColor("_Color"); val6.SetColor("_Color", new Color(tintColor.r, tintColor.g, tintColor.b, color4.a)); } val5.trailMaterial = val6; } } [IteratorStateMachine(typeof(<LoadRequiredPrefabs>d__52))] private IEnumerator LoadRequiredPrefabs() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadRequiredPrefabs>d__52(0) { <>4__this = this }; } private void EnsureSurvivorBanksLoaded(string context) { if (!ForceSurvivorBanks && context != "DeferredStart") { return; } string[] array = survivorBanks; foreach (string text in array) { AkBankManager.LoadBank(text, true, true); if (BankDebugEnabled) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[GaussShotgun] Directly loading bank '" + text + "' (context=" + context + ")")); } if (AkSoundEngine.GetIDFromString("Play_commando_R") == 0 && BankDebugEnabled) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[GaussShotgun] Bank " + text + " loaded but Play_commando_R still not available!")); } } if (!banksVerified) { ((MonoBehaviour)this).StartCoroutine(VerifyBanksNextFrame(context)); } } [IteratorStateMachine(typeof(<VerifyBanksNextFrame>d__54))] private IEnumerator VerifyBanksNextFrame(string context) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <VerifyBanksNextFrame>d__54(0) { <>4__this = this, context = context }; } private void OnDestroy() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown Stage.onStageStartGlobal -= OnStageStartGlobal; GenericSkill.SetSkillOverride -= new hook_SetSkillOverride(GenericSkill_SetSkillOverride); } private void GenericSkill_SetSkillOverride(orig_SetSkillOverride orig, GenericSkill self, object source, SkillDef skillDef, SkillOverridePriority priority) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (self.skillDef is GaussShotgunSkillDef && (Object)(object)self.characterBody != (Object)null) { GaussShotgunStockTracker gaussShotgunStockTracker = ((Component)self.characterBody).GetComponent<GaussShotgunStockTracker>(); if ((Object)(object)gaussShotgunStockTracker == (Object)null) { gaussShotgunStockTracker = ((Component)self.characterBody).gameObject.AddComponent<GaussShotgunStockTracker>(); Debug.Log((object)"[GaussShotgun] Created GaussShotgunStockTracker in SetSkillOverride hook"); } gaussShotgunStockTracker.savedStock = self.stock; gaussShotgunStockTracker.savedRechargeStopwatch = self.rechargeStopwatch; Debug.Log((object)$"[GaussShotgun] SetSkillOverride hook - Saved stock={self.stock}, rechargeStopwatch={self.rechargeStopwatch:F2} BEFORE override (skillDef={skillDef?.skillName})"); } orig.Invoke(self, source, skillDef, priority); } private void SetupCustomCrosshair() { try { if ((Object)(object)assetBundle != (Object)null) { customCrosshairPrefab = PrefabAPI.InstantiateClone(assetBundle.LoadAsset<GameObject>("GaussCrosshair"), "GaussShotgunCrosshair", false); if ((Object)(object)customCrosshairPrefab != (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded custom crosshair prefab from asset bundle"); Sprite val = assetBundle.LoadAsset<Sprite>("StockHexIcon"); if ((Object)(object)val != (Object)null) { CreateStockDisplay(val); } if ((Object)(object)gaussShotgunSkillDef != (Object)null) { GaussShotgunSkillDef.crosshairOverride = customCrosshairPrefab; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Crosshair override set on skill def"); } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not load GaussCrosshair from asset bundle"); } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Asset bundle not loaded, cannot setup custom crosshair"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Custom crosshair setup complete"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error setting up custom crosshair: " + ex.Message)); } } private void CreateStockDisplay(Sprite stockSprite) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0086: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)customCrosshairPrefab == (Object)null || (Object)(object)stockSprite == (Object)null) { return; } try { CrosshairController component = customCrosshairPrefab.GetComponent<CrosshairController>(); if ((Object)(object)component == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"No CrosshairController on prefab!"); return; } GameObject val = new GameObject("StockContainer"); val.transform.SetParent(customCrosshairPrefab.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0.5f, 0f); val2.anchorMax = new Vector2(0.5f, 0f); val2.pivot = new Vector2(0.5f, 1f); val2.anchoredPosition = new Vector2(0f, -20f); val2.sizeDelta = new Vector2(200f, 30f); HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 4f; ((LayoutGroup)val3).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false; SkillStockSpriteDisplay[] skillStockSpriteDisplays = component.skillStockSpriteDisplays; int num = stockConfig?.Value ?? gaussShotgunSkillDef?.baseMaxStock ?? 8; int num2 = Mathf.Min(num, 10); SkillStockSpriteDisplay[] array = (SkillStockSpriteDisplay[])(object)new SkillStockSpriteDisplay[skillStockSpriteDisplays.Length + num2]; for (int i = 0; i < skillStockSpriteDisplays.Length; i++) { array[i] = skillStockSpriteDisplays[i]; if (array[i].maximumStockCountToBeValid > 0 && array[i].maximumStockCountToBeValid < num) { array[i].maximumStockCountToBeValid = num; } } for (int j = 0; j < num2; j++) { GameObject val4 = new GameObject($"StockIcon{j + 1}"); val4.transform.SetParent(val.transform, false); RectTransform val5 = val4.AddComponent<RectTransform>(); val5.sizeDelta = new Vector2(20f, 20f); Image val6 = val4.AddComponent<Image>(); val6.sprite = stockSprite; ((Graphic)val6).color = Color.white; array[skillStockSpriteDisplays.Length + j] = new SkillStockSpriteDisplay { target = val4, skillSlot = (SkillSlot)0, requiredSkillDef = gaussShotgunSkillDef, minimumStockCountToBeValid = j + 1, maximumStockCountToBeValid = num }; } component.skillStockSpriteDisplays = array; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Created stock display with {num2} icons"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Error creating stock display: " + ex.Message)); } } private void SetupGaussShotgun() { //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_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) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_0145: 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) GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Engi/EngiBody.prefab").WaitForCompletion(); SkillLocator component = val.GetComponent<SkillLocator>(); SkillFamily skillFamily = component.primary.skillFamily; GaussShotgunSkillDef gaussShotgunSkillDef = ScriptableObject.CreateInstance<GaussShotgunSkillDef>(); ((SkillDef)gaussShotgunSkillDef).activationState = new SerializableEntityStateType(typeof(GaussShotgunFire)); ((SkillDef)gaussShotgunSkillDef).baseMaxStock = stockConfig?.Value ?? 4; ((SkillDef)gaussShotgunSkillDef).rechargeStock = 1; ((SkillDef)gaussShotgunSkillDef).baseRechargeInterval = ReloadPerRoundBaseTime; ((SkillDef)gaussShotgunSkillDef).skillDescriptionToken = "ENGI_GAUSS_SHOTGUN_DESCRIPTION"; ((SkillDef)gaussShotgunSkillDef).skillName = "GaussShotgun"; ((SkillDef)gaussShotgunSkillDef).skillNameToken = "ENGI_GAUSS_SHOTGUN_NAME"; ((SkillDef)gaussShotgunSkillDef).activationStateMachineName = "Weapon"; ((SkillDef)gaussShotgunSkillDef).beginSkillCooldownOnSkillEnd = false; ((SkillDef)gaussShotgunSkillDef).fullRestockOnAssign = true; ((SkillDef)gaussShotgunSkillDef).interruptPriority = (InterruptPriority)1; ((SkillDef)gaussShotgunSkillDef).isCombatSkill = true; ((SkillDef)gaussShotgunSkillDef).cancelSprintingOnActivation = true; ((SkillDef)gaussShotgunSkillDef).canceledFromSprinting = false; ((SkillDef)gaussShotgunSkillDef).mustKeyPress = false; ((SkillDef)gaussShotgunSkillDef).icon = gaussShotgunIcon; ((SkillDef)gaussShotgunSkillDef).requiredStock = 1; ((SkillDef)gaussShotgunSkillDef).stockToConsume = 0; ((SkillDef)gaussShotgunSkillDef).attackSpeedBuffsRestockSpeed = true; ContentAddition.AddSkillDef((SkillDef)(object)gaussShotgunSkillDef); Array.Resize(ref skillFamily.variants, skillFamily.variants.Length + 1); Variant[] variants = skillFamily.variants; int num = skillFamily.variants.Length - 1; Variant val2 = new Variant { skillDef = (SkillDef)(object)gaussShotgunSkillDef, unlockableDef = null }; ((Variant)(ref val2)).viewableNode = new Node(((SkillDef)gaussShotgunSkillDef).skillNameToken, false, (Node)null); variants[num] = val2; EngiGaussShotgunPlugin.gaussShotgunSkillDef = (SkillDef?)(object)gaussShotgunSkillDef; LanguageAPI.Add("ENGI_GAUSS_SHOTGUN_NAME", "Gauss Shotgun"); LanguageAPI.Add("ENGI_GAUSS_SHOTGUN_DESCRIPTION", $"Fire a close-range blast of pellets, dealing <style=cIsDamage>8x{(int)((damageConfig?.Value ?? 0.6f) * 100f)}% damage</style>. " + $"Holds {stockConfig?.Value ?? 4} total rounds."); } } public class GaussShotgunSkillDef : SkillDef { public class InstanceData : BaseSkillInstanceData { public int stockToRestore; } public static GameObject? crosshairOverride; public override float GetRechargeInterval(GenericSkill skillSlot) { if ((Object)(object)((skillSlot != null) ? skillSlot.characterBody : null) != (Object)null) { return base.baseRechargeInterval / skillSlot.characterBody.attackSpeed; } return base.baseRechargeInterval; } public override BaseSkillInstanceData OnAssigned(GenericSkill skillSlot) { Debug.Log((object)$"[GaussShotgun] OnAssigned called - skillSlot.stock={skillSlot.stock}, rechargeStopwatch={skillSlot.rechargeStopwatch:F2}"); if ((Object)(object)crosshairOverride != (Object)null) { CharacterBody component = ((Component)skillSlot).GetComponent<CharacterBody>(); if ((Object)(object)component != (Object)null) { CrosshairUtils.RequestOverrideForBody(component, crosshairOverride, (OverridePriority)1); } } CharacterBody characterBody = skillSlot.characterBody; int num = -1; float num2 = -1f; Debug.Log((object)$"[GaussShotgun] OnAssigned - charBody={(Object)(object)characterBody != (Object)null}"); if ((Object)(object)characterBody != (Object)null) { GaussShotgunStockTracker component2 = ((Component)characterBody).GetComponent<GaussShotgunStockTracker>(); Debug.Log((object)$"[GaussShotgun] OnAssigned - stockTracker={(Object)(object)component2 != (Object)null}"); if ((Object)(object)component2 != (Object)null) { Debug.Log((object)$"[GaussShotgun] OnAssigned - stockTracker.savedStock={component2.savedStock}, savedRechargeStopwatch={component2.savedRechargeStopwatch:F2}"); if (component2.savedStock >= 0) { num = component2.savedStock; num2 = component2.savedRechargeStopwatch; component2.savedStock = -1; component2.savedRechargeStopwatch = 0f; Debug.Log((object)$"[GaussShotgun] Found saved stock: {num}, recharge: {num2:F2}, will restore after base call"); } else { Debug.Log((object)$"[GaussShotgun] savedStock is negative ({component2.savedStock}), not restoring"); } } else { Debug.LogWarning((object)"[GaussShotgun] OnAssigned: No GaussShotgunStockTracker found on character body!"); } } else { Debug.LogError((object)"[GaussShotgun] OnAssigned: CharacterBody is NULL!"); } Debug.Log((object)$"[GaussShotgun] Calling base.OnAssigned() - stock before base call: {skillSlot.stock}"); BaseSkillInstanceData result = ((SkillDef)this).OnAssigned(skillSlot); Debug.Log((object)$"[GaussShotgun] After base.OnAssigned() - stock is now: {skillSlot.stock}, rechargeStopwatch: {skillSlot.rechargeStopwatch:F2}"); if (num >= 0) { Debug.Log((object)$"[GaussShotgun] Overriding stock from {skillSlot.stock} to {num}"); skillSlot.stock = num; skillSlot.rechargeStopwatch = num2; Debug.Log((object)$"[GaussShotgun] Restored stock to {num} and rechargeStopwatch to {num2:F2} on reassign (overriding fullRestockOnAssign) - final stock: {skillSlot.stock}, recharge: {skillSlot.rechargeStopwatch:F2}"); if ((Object)(object)characterBody != (Object)null && num < skillSlot.maxStock) { GaussReloadController gaussReloadController = ((Component)characterBody).GetComponent<GaussReloadController>(); if ((Object)(object)gaussReloadController == (Object)null) { gaussReloadController = ((Component)characterBody).gameObject.AddComponent<GaussReloadController>(); Debug.Log((object)"[GaussShotgun] Created GaussReloadController on reassign"); } gaussReloadController.RestoreReloadState(skillSlot, characterBody, num2); Debug.Log((object)$"[GaussShotgun] Restarted GaussReloadController with restored stopwatch {num2:F2}"); } } else { Debug.Log((object)$"[GaussShotgun] No stock to restore, keeping default stock: {skillSlot.stock}"); } return result; } public override void OnUnassigned(GenericSkill skillSlot) { Debug.Log((object)"[GaussShotgun] OnUnassigned called - stock saving was already handled by SetSkillOverride hook"); ((SkillDef)this).OnUnassigned(skillSlot); } public override void OnFixedUpdate(GenericSkill skillSlot, float deltaTime) { CharacterBody characterBody = skillSlot.characterBody; if (Object.op_Implicit((Object)(object)characterBody)) { GaussReloadController gaussReloadController = ((Component)characterBody).GetComponent<GaussReloadController>(); if (!Object.op_Implicit((Object)(object)gaussReloadController)) { gaussReloadController = ((Component)characterBody).gameObject.AddComponent<GaussReloadController>(); } if (skillSlot.stock < skillSlot.maxStock) { gaussReloadController.BeginReload(skillSlot, characterBody, characterBody.attackSpeed); } else { gaussReloadController.StopReload(skillSlot); } } } public override bool CanExecute(GenericSkill skillSlot) { if (skillSlot.stock > 0) { return ((SkillDef)this).CanExecute(skillSlot); } return false; } } public class GaussShotgunFire : BaseState { public static float baseMaxDuration = 0.1f; public static float baseMinDuration = 0.1f; private float maxDuration; private float minDuration; private bool buttonReleased; private bool shotFired; private string muzzleString = "MuzzleRight"; private string muzzleString2 = "MuzzleLeft"; public static GameObject? muzzleEffectPrefab; public static GameObject? tracerEffectPrefab; public static GameObject? hitEffectPrefab; public static GameObject? customMuzzleEffectPrefab; public static GameObject? customHitEffectPrefab; public static bool customEffectsCreated = false; public static readonly string enemyImpactEvent = "Play_commando_R"; public static readonly string worldImpactEvent = "Play_commando_R"; private bool hasPlayedImpactThisShot = false; public override void OnEnter() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); maxDuration = baseMaxDuration / base.attackSpeedStat; minDuration = baseMinDuration / base.attackSpeedStat; if (!Object.op_Implicit((Object)(object)muzzleEffectPrefab)) { muzzleEffectPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/Muzzleflash1.prefab").WaitForCompletion(); } if (!Object.op_Implicit((Object)(object)tracerEffectPrefab)) { tracerEffectPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Engi/TracerEngiTurret.prefab").WaitForCompletion(); } if (!Object.op_Implicit((Object)(object)hitEffectPrefab)) { hitEffectPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Commando/HitsparkCommando.prefab").WaitForCompletion(); } GameObject val = customMuzzleEffectPrefab ?? muzzleEffectPrefab; if (Object.op_Implicit((Object)(object)hitEffectPrefab)) { EffectComponent component = hitEffectPrefab.GetComponent<EffectComponent>(); if (!Object.op_Implicit((Object)(object)component) || string.IsNullOrEmpty(component.soundName)) { Debug.Log((object)"[GaussShotgun] hitEffectPrefab has no EffectComponent soundName; will rely on manual impact sounds."); } else { Debug.Log((object)("[GaussShotgun] hitEffectPrefab soundName='" + component.soundName + "'")); } } Util.PlaySound("Play_engi_M1_shoot", ((EntityState)this).gameObject); Util.PlaySound(worldImpactEvent, ((EntityState)this).gameObject); ((EntityState)this).PlayAnimation("Gesture Right Cannon, Additive", "FireGrenadeRight", "FireGrenadeRight.playbackRate", maxDuration, 0f); ((EntityState)this).PlayAnimation("Gesture Left Cannon, Additive", "FireGrenadeLeft", "FireGrenadeLeft.playbackRate", maxDuration, 0f); if ((Object)(object)val != (Object)null) { EffectManager.SimpleMuzzleFlash(val, ((EntityState)this).gameObject, muzzleString, false); EffectManager.SimpleMuzzleFlash(val, ((EntityState)this).gameObject, muzzleString2, false); } if (((EntityState)this).isAuthority) { FireShotgun(); } if (!Object.op_Implicit((Object)(object)((EntityState)this).gameObject.GetComponent<AkGameObj>())) { ((EntityState)this).gameObject.AddComponent<AkGameObj>(); Debug.Log((object)"[GaussShotgun] Added AkGameObj to ensure Wwise events post correctly."); } } private void FireShotgun() { //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) Ray aimRay = ((BaseState)this).GetAimRay(); float perPelletDamageCoeff = 0.6f; ((BaseState)this).AddRecoil(-4.5f, -1f, -1f, 4f); ((EntityState)this).characterBody.AddSpreadBloom(0.3f); hasPlayedImpactThisShot = false; GameObject hitToUse = customHitEffectPrefab ?? hitEffectPrefab; FireFromMuzzle(muzzleString); FireFromMuzzle(muzzleString2); shotFired = true; void FireFromMuzzle(string muzzle) { //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_0017: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_004b: 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_005e: 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_009c: 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_00b2: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0111: 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_0127: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_014f: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) BulletAttack val = new BulletAttack { owner = ((EntityState)this).gameObject, weapon = ((EntityState)this).gameObject, origin = ((Ray)(ref aimRay)).origin, aimVector = ((Ray)(ref aimRay)).direction, maxDistance = 80f, bulletCount = 8u, damage = perPelletDamageCoeff * base.damageStat, isCrit = Util.CheckRoll(base.critStat, ((EntityState)this).characterBody.master), force = 9f, procCoefficient = 0.45f, procChainMask = default(ProcChainMask), radius = 0.15f, falloffModel = (FalloffModel)1, smartCollision = true, stopperMask = CommonMasks.bullet, hitMask = CommonMasks.bullet, muzzleName = muzzle, HitEffectNormal = true, minSpread = 0f, maxSpread = 3.5f, spreadPitchScale = 1f, spreadYawScale = 1f, cheapMultiBullet = false, allowTrajectoryAimAssist = false, queryTriggerInteraction = (QueryTriggerInteraction)0, hitCallback = (HitCallback)delegate(BulletAttack bulletAttack, ref BulletHit hitInfo) { bool result = BulletAttack.defaultHitCallback.Invoke(bulletAttack, ref hitInfo); if (!hasPlayedImpactThisShot && EngiGaussShotgunPlugin.DebugAllPelletImpactSound) { if (Object.op_Implicit((Object)(object)hitInfo.hitHurtBox)) { Util.PlaySound(enemyImpactEvent, ((Component)hitInfo.hitHurtBox.healthComponent).gameObject); } else { Util.PlaySound(worldImpactEvent, ((EntityState)this).gameObject); } } else if (!hasPlayedImpactThisShot) { hasPlayedImpactThisShot = true; if (Object.op_Implicit((Object)(object)hitInfo.hitHurtBox)) { Util.PlaySound(enemyImpactEvent, ((Component)hitInfo.hitHurtBox.healthComponent).gameObject); } else { Util.PlaySound(worldImpactEvent, ((EntityState)this).gameObject); } } return result; } }; if ((Object)(object)tracerEffectPrefab != (Object)null) { val.tracerEffectPrefab = tracerEffectPrefab; } if ((Object)(object)hitToUse != (Object)null) { val.hitEffectPrefab = hitToUse; } val.damageType.damageSource = (DamageSource)1; val.Fire(); Debug.Log((object)string.Format("[GaussShotgun] Fired muzzle={0} dmgPerPellet={1:F2} count={2} hitFx={3}", muzzle, perPelletDamageCoeff * base.damageStat, val.bulletCount, Object.op_Implicit((Object)(object)hitEffectPrefab) ? ((Object)hitEffectPrefab).name : "NULL")); } } public override void OnExit() { if (!buttonReleased && Object.op_Implicit((Object)(object)((EntityState)this).characterBody)) { ((EntityState)this).characterBody.SetSpreadBloom(0f, false); } ((EntityState)this).OnExit(); } public override void FixedUpdate() { if (shotFired) { GenericSkill val = ((EntityState)this).skillLocator?.primary; if ((Object)(object)val != (Object)null) { val.DeductStock(1); GaussReloadController gaussReloadController = ((Component)((EntityState)this).characterBody).GetComponent<GaussReloadController>(); if (!Object.op_Implicit((Object)(object)gaussReloadController)) { gaussReloadController = ((Component)((EntityState)this).characterBody).gameObject.AddComponent<GaussReloadController>(); } gaussReloadController.BeginReload(val, ((EntityState)this).characterBody, base.attackSpeedStat); } shotFired = false; } ((EntityState)this).FixedUpdate(); buttonReleased |= !((EntityState)this).inputBank.skill1.down; if (((EntityState)this).fixedAge >= maxDuration && ((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { //IL_0027: 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_002a: Unknown result type (might be due to invalid IL or missing references) if (buttonReleased && ((EntityState)this).fixedAge >= minDuration) { return (InterruptPriority)0; } return (InterruptPriority)2; } } public class GaussShotgunReload : BaseState { public static GameObject? reloadEffectPrefab; public override void OnEnter() { //IL_003d: 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) ((BaseState)this).OnEnter(); if (!((EntityState)this).isAuthority) { ((EntityState)this).outer.SetNextStateToMain(); return; } if (!Object.op_Implicit((Object)(object)reloadEffectPrefab)) { reloadEffectPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/Muzzleflash.prefab").WaitForCompletion(); } if (Object.op_Implicit((Object)(object)reloadEffectPrefab)) { EffectManager.SimpleMuzzleFlash(reloadEffectPrefab, ((EntityState)this).gameObject, "MuzzleCenter", false); } GaussReloadController gaussReloadController = ((Component)((EntityState)this).characterBody).GetComponent<GaussReloadController>(); if (!Object.op_Implicit((Object)(object)gaussReloadController)) { gaussReloadController = ((Component)((EntityState)this).characterBody).gameObject.AddComponent<GaussReloadController>(); } gaussReloadController.BeginReload(((EntityState)this).skillLocator.primary, ((EntityState)this).characterBody, base.attackSpeedStat); ((EntityState)this).outer.SetNextStateToMain(); } public override InterruptPriority GetMinimumInterruptPriority() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return (InterruptPriority)0; } } public class GaussShotgunStockTracker : MonoBehaviour { public int savedStock = -1; public float savedRechargeStopwatch = 0f; } public class GaussReloadController : MonoBehaviour { private GenericSkill? skill; private CharacterBody? body; private float perRoundInterval; private float intervalStopwatch; private bool reloading; private bool skipFirstRoundSound; private int targetMax; public void RestoreReloadState(GenericSkill primary, CharacterBody cb, float restoredStopwatch) { if (!((Object)(object)primary == (Object)null) && !((Object)(object)cb == (Object)null)) { skill = primary; body = cb; targetMax = skill.maxStock; GaussShotgunSkillDef gaussShotgunSkillDef = skill.skillDef as GaussShotgunSkillDef; perRoundInterval = (((Object)(object)gaussShotgunSkillDef != (Object)null) ? ((SkillDef)gaussShotgunSkillDef).GetRechargeInterval(skill) : skill.baseRechargeInterval); intervalStopwatch = restoredStopwatch; if (skill.stock < targetMax) { reloading = true; skipFirstRoundSound = true; Debug.Log((object)$"[GaussReloadController] RestoreReloadState: reloading={reloading}, intervalStopwatch={intervalStopwatch:F2}, perRoundInterval={perRoundInterval:F2}"); } } } public void BeginReload(GenericSkill primary, CharacterBody cb, float atkSpeed) { if ((Object)(object)primary == (Object)null || (Object)(object)cb == (Object)null) { return; } if ((Object)(object)skill != (Object)(object)primary) { skill = primary; targetMax = skill.maxStock; } body = cb; if (skill.stock >= targetMax) { StopReload(primary); return; } float num = perRoundInterval; GaussShotgunSkillDef gaussShotgunSkillDef = skill.skillDef as GaussShotgunSkillDef; float num2 = (((Object)(object)gaussShotgunSkillDef != (Object)null) ? ((SkillDef)gaussShotgunSkillDef).GetRechargeInterval(skill) : skill.baseRechargeInterval); perRoundInterval = num2; if (num > 0f && intervalStopwatch > 0f) { float num3 = Mathf.Clamp01(intervalStopwatch / num); intervalStopwatch = num3 * perRoundInterval; } else { intervalStopwatch = Mathf.Min(intervalStopwatch, perRoundInterval); } if (!reloading) { reloading = true; skipFirstRoundSound = skill.stock == 0; if (!skipFirstRoundSound && (Object)(object)body != (Object)null && ((NetworkBehaviour)body).hasAuthority) { Util.PlaySound(EngiGaussShotgunPlugin.ReloadStartSoundEvent, ((Component)body).gameObject); } } } public void StopReload(GenericSkill? requestingSkill = null) { if (!((Object)(object)requestingSkill != (Object)null) || !((Object)(object)skill != (Object)null) || !((Object)(object)requestingSkill != (Object)(object)skill)) { reloading = false; intervalStopwatch = 0f; skipFirstRoundSound = false; if ((Object)(object)skill != (Object)null) { skill.rechargeStopwatch = 0f; } } } private void FixedUpdate() { if (!reloading || (Object)(object)skill == (Object)null || (Object)(object)body == (Object)null) { return; } targetMax = skill.maxStock; if (skill.stock >= targetMax) { StopReload(skill); return; } float num = perRoundInterval; GaussShotgunSkillDef gaussShotgunSkillDef = skill.skillDef as GaussShotgunSkillDef; float num2 = (((Object)(object)gaussShotgunSkillDef != (Object)null) ? ((SkillDef)gaussShotgunSkillDef).GetRechargeInterval(skill) : skill.baseRechargeInterval); perRoundInterval = num2; if (num > 0f && !Mathf.Approximately(num, perRoundInterval)) { float num3 = Mathf.Clamp01(intervalStopwatch / num); intervalStopwatch = num3 * perRoundInterval; } intervalStopwatch += Time.fixedDeltaTime; if (intervalStopwatch > perRoundInterval) { intervalStopwatch = perRoundInterval; } skill.rechargeStopwatch = intervalStopwatch; skill.RecalculateValues(); if (intervalStopwatch >= perRoundInterval) { intervalStopwatch = 0f; if (NetworkServer.active) { skill.AddOneStock(); } if (!skipFirstRoundSound && EngiGaussShotgunPlugin.ReloadPerRoundSoundEnabled && (Object)(object)body != (Object)null && ((NetworkBehaviour)body).hasAuthority) { Util.PlaySound(EngiGaussShotgunPlugin.ReloadPerRoundSoundEvent, ((Component)body).gameObject); } skipFirstRoundSound = false; if (skill.stock >= targetMax) { StopReload(skill); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }