using 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)
{
}
}
}