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 EngineerGaussShotgun v0.3.0
BepInEx/plugins/EngiAlternateSkills.dll
Decompiled 7 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) { } } }