using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.Captain.Weapon; using EntityStates.CaptainSupplyDrop; using IL.RoR2; using KinematicCharacterController; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.EntityStates; using On.EntityStates.Captain.Weapon; using On.RoR2; using On.RoR2.Networking; using On.RoR2.Orbs; using On.RoR2.Projectile; using On.RoR2.Skills; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Achievements; using RoR2.Hologram; using RoR2.Networking; using RoR2.Orbs; using RoR2.Projectile; using RoR2.Skills; using RoR2.Stats; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; [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("Admiral")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+8bc69138c39bdbf02f9c915547e7ffca95080f4d")] [assembly: AssemblyProduct("Admiral")] [assembly: AssemblyTitle("Admiral")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ThinkInvisible.Admiral; [BepInDependency("com.bepis.r2api", "5.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.ThinkInvisible.Admiral", "Admiral", "3.0.0")] public class AdmiralPlugin : BaseUnityPlugin { public const string ModVer = "3.0.0"; public const string ModName = "Admiral"; public const string ModGuid = "com.ThinkInvisible.Admiral"; internal static ManualLogSource _logger; internal static AssetBundle resources; internal static ConfigFile cfgFile; private FilingDictionary allModules; public void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown _logger = ((BaseUnityPlugin)this).Logger; cfgFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "com.ThinkInvisible.Admiral.cfg"), true); using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Admiral.admiral_assets")) { resources = AssetBundle.LoadFromStream(stream); } Module.SetupModuleClass(); allModules = Module.InitModules(new Module.ModInfo { displayName = "Admiral", longIdentifier = "Admiral", shortIdentifier = "ADML", mainConfigFile = cfgFile }); Module.SetupAll_PluginAwake(allModules); } public void Start() { Module.SetupAll_PluginStart(allModules); } private void Update() { if (RoR2Application.loadFinished) { AutoConfigModule.Update(); } } } public static class CommonCode { public static GameObject ModifyVanillaPrefab(string addressablePath, string newName, bool shouldNetwork, Func modifierCallback) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) GameObject val = PrefabAPI.InstantiateClone(Addressables.LoadAssetAsync((object)addressablePath).WaitForCompletion(), "Temporary Setup Prefab", false); GameObject val2 = modifierCallback(val); GameObject result = PrefabAPI.InstantiateClone(val2, newName, shouldNetwork); Object.Destroy((Object)(object)val); Object.Destroy((Object)(object)val2); return result; } public static float Wrap(float x, float min, float max) { if (x < min) { return max - (min - x) % (max - min); } return min + (x - min) % (max - min); } } public static class Compat_RiskOfOptions { public struct OptionIdentityStrings { public string category; public string name; public string description; public string modName; public string modGuid; } private static bool? _enabled; public static bool enabled { get { bool valueOrDefault = _enabled.GetValueOrDefault(); if (!_enabled.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); _enabled = valueOrDefault; } return _enabled.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SetupMod(string modGuid, string modName, string description, Sprite icon = null) { ModSettingsManager.SetModDescription(description, modGuid, modName); if ((Object)(object)icon != (Object)null) { ModSettingsManager.SetModIcon(icon, modGuid, modName); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_CheckBox(ConfigEntry configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(configEntry, new CheckBoxConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Slider(ConfigEntry configEntry, OptionIdentityStrings ident, float min, float max, string formatString, bool restartRequired, Func isDisabledDelegate) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_006e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(configEntry, new SliderConfig { category = ident.category, name = ident.name, max = max, min = min, formatString = formatString, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_IntSlider(ConfigEntry configEntry, OptionIdentityStrings ident, int min, int max, string formatString, bool restartRequired, Func isDisabledDelegate) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_006e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(configEntry, new IntSliderConfig { category = ident.category, name = ident.name, max = max, min = min, formatString = formatString, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Choice(ConfigEntryBase configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new ChoiceOption(configEntry, new ChoiceConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Keybind(ConfigEntry configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new KeyBindOption(configEntry, new KeyBindConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_String(ConfigEntry configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(configEntry, new InputFieldConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_StepSlider(ConfigEntry configEntry, OptionIdentityStrings ident, float min, float max, float step, string formatString, bool restartRequired, Func isDisabledDelegate) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0076: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StepSliderOption(configEntry, new StepSliderConfig { category = ident.category, name = ident.name, min = min, max = max, formatString = formatString, increment = step, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Button(OptionIdentityStrings ident, string text, UnityAction del) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new GenericButtonOption(ident.name, ident.category, ident.description, text, del), ident.modGuid, ident.modName); } } public class CaptainBeaconDecayer : MonoBehaviour { public float lifetime = 15f; public bool silent = false; private float stopwatch = 0f; private GenericEnergyComponent energyCpt; public static float lifetimeDropAdjust { get; internal set; } = 4f; private void Awake() { energyCpt = ((Component)this).gameObject.GetComponent(); } private void FixedUpdate() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown stopwatch += Time.fixedDeltaTime; if (Object.op_Implicit((Object)(object)energyCpt)) { energyCpt.capacity = lifetime; energyCpt.energy = lifetime - stopwatch + lifetimeDropAdjust; } if (stopwatch >= lifetime + lifetimeDropAdjust) { if (!silent) { EffectManager.SpawnEffect(LegacyResourcesAPI.Load("prefabs/effects/omnieffect/OmniExplosionVFXEngiTurretDeath"), new EffectData { origin = ((Component)this).transform.position, scale = 5f }, true); } Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class FilingDictionary : IEnumerable, IEnumerable { private readonly Dictionary _dict = new Dictionary(); public int Count => _dict.Count; public void Add(T inst) { _dict.Add(inst.GetType(), inst); } public void Add(subT inst) where subT : T { _dict.Add(typeof(subT), (T)(object)inst); } public void Set(subT inst) where subT : T { _dict[typeof(subT)] = (T)(object)inst; } public subT Get() where subT : T { return (subT)(object)_dict[typeof(subT)]; } public void Remove(T inst) { _dict.Remove(inst.GetType()); } public void RemoveWhere(Func predicate) { foreach (T item in _dict.Values.Where(predicate).ToList()) { _dict.Remove(item.GetType()); } } public IEnumerator GetEnumerator() { return _dict.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public ReadOnlyFilingDictionary AsReadOnly() { return new ReadOnlyFilingDictionary(this); } } public class ReadOnlyFilingDictionary : IReadOnlyCollection, IEnumerable, IEnumerable { private readonly FilingDictionary baseCollection; public int Count => baseCollection.Count; public ReadOnlyFilingDictionary(FilingDictionary baseCollection) { this.baseCollection = baseCollection; } public IEnumerator GetEnumerator() { return baseCollection.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return baseCollection.GetEnumerator(); } } public class AutoConfigBinding { public enum DeferType { UpdateImmediately, WaitForNextStage, WaitForRunEnd, NeverAutoUpdate } internal static readonly List instances = new List(); internal static readonly Dictionary stageDirtyInstances = new Dictionary(); internal static readonly Dictionary runDirtyInstances = new Dictionary(); internal bool isOverridden = false; public AutoConfigContainer owner { get; internal set; } public object target { get; internal set; } public ConfigEntryBase configEntry { get; internal set; } public PropertyInfo boundProperty { get; internal set; } public string modName { get; internal set; } public AutoConfigUpdateActionsAttribute updateEventAttribute { get; internal set; } public MethodInfo propGetter { get; internal set; } public MethodInfo propSetter { get; internal set; } public Type propType { get; internal set; } public object boundKey { get; internal set; } public bool onDict { get; internal set; } public bool allowConCmd { get; internal set; } public object cachedValue { get; internal set; } public DeferType deferType { get; internal set; } public string readablePath => modName + "/" + configEntry.Definition.Section + "/" + configEntry.Definition.Key; internal static void CleanupDirty(bool isRunEnd) { AdmiralPlugin._logger.LogDebug((object)$"Stage ended; applying {stageDirtyInstances.Count} deferred config changes..."); foreach (AutoConfigBinding key in stageDirtyInstances.Keys) { key.DeferredUpdateProperty(stageDirtyInstances[key].Item1, stageDirtyInstances[key].Item2); } stageDirtyInstances.Clear(); if (!isRunEnd) { return; } AdmiralPlugin._logger.LogDebug((object)$"Run ended; applying {runDirtyInstances.Count} deferred config changes..."); foreach (AutoConfigBinding key2 in runDirtyInstances.Keys) { key2.DeferredUpdateProperty(runDirtyInstances[key2], silent: true); } runDirtyInstances.Clear(); } internal AutoConfigBinding() { instances.Add(this); } ~AutoConfigBinding() { if (instances.Contains(this)) { instances.Remove(this); } } internal void OverrideProperty(object newValue, bool silent = false) { if (!isOverridden) { runDirtyInstances[this] = cachedValue; } isOverridden = true; UpdateProperty(newValue, silent); } private void DeferredUpdateProperty(object newValue, bool silent = false) { object oldValue = propGetter.Invoke(target, (!onDict) ? new object[0] : new object[1] { boundKey }); propSetter.Invoke(target, (!onDict) ? new object[1] { newValue } : new object[2] { boundKey, newValue }); AutoConfigUpdateActionTypes autoConfigUpdateActionTypes = updateEventAttribute?.flags ?? AutoConfigUpdateActionTypes.None; AutoConfigUpdateActionsAttribute autoConfigUpdateActionsAttribute = updateEventAttribute; if (autoConfigUpdateActionsAttribute != null && !autoConfigUpdateActionsAttribute.ignoreDefault) { autoConfigUpdateActionTypes |= owner.defaultEnabledUpdateFlags; } cachedValue = newValue; owner.OnConfigChanged(new AutoConfigUpdateActionEventArgs { flags = autoConfigUpdateActionTypes, oldValue = oldValue, newValue = newValue, target = this, silent = silent }); } internal void UpdateProperty(object newValue, bool silent = false) { if (deferType == DeferType.UpdateImmediately || (Object)(object)Run.instance == (Object)null || !((Behaviour)Run.instance).enabled) { DeferredUpdateProperty(newValue, silent); } else if (deferType == DeferType.WaitForNextStage) { stageDirtyInstances[this] = (newValue, silent); } else if (deferType == DeferType.WaitForRunEnd) { runDirtyInstances[this] = newValue; } else { AdmiralPlugin._logger.LogWarning((object)("Something attempted to set the value of an AutoConfigBinding with the DeferForever flag: \"" + readablePath + "\"")); } } public static (List results, string errorMsg) FindFromPath(string path1, string path2, string path3) { string p1u = path1.ToUpper(); string p2u = path2?.ToUpper(); string p3u = path3?.ToUpper(); List matchesLevel1 = new List(); List matchesLevel2 = new List(); List matchesLevel3 = new List(); List matchesLevel4 = new List(); instances.ForEach(delegate(AutoConfigBinding x) { if (x.allowConCmd) { string key = x.configEntry.Definition.Key; string text = key.ToUpper(); string section = x.configEntry.Definition.Section; string text2 = section.ToUpper(); string text3 = x.modName; string text4 = text3.ToUpper(); if (path2 == null) { if (text.Contains(p1u) || text2.Contains(p1u) || text4.Contains(p1u)) { matchesLevel1.Add(x); matchesLevel2.Add(x); if (text == p1u) { matchesLevel3.Add(x); if (key == path1) { matchesLevel4.Add(x); } } } } else if (path3 == null) { bool flag = text4.Contains(p1u); bool flag2 = text2.Contains(p1u); bool flag3 = text2.Contains(p2u); bool flag4 = text.Contains(p2u); if ((flag && flag3) || (flag2 && flag4) || (flag && flag4)) { matchesLevel1.Add(x); if (!(flag && flag4)) { matchesLevel2.Add(x); bool flag5 = text3.Contains(path1); bool flag6 = section.Contains(path1); bool flag7 = section.Contains(path2); bool flag8 = key.Contains(path2); if ((flag5 && flag7) || (flag6 && flag8)) { matchesLevel3.Add(x); bool flag9 = text3 == path1; bool flag10 = section == path1; bool flag11 = section == path2; bool flag12 = key == path2; if ((flag9 && flag11) || (flag10 && flag12)) { matchesLevel4.Add(x); } } } } } else if (text.Contains(p3u) && text2.Contains(p2u) && text4.Contains(p1u)) { matchesLevel1.Add(x); matchesLevel2.Add(x); if (text4 == p3u && text2 == p2u && text == p1u) { matchesLevel3.Add(x); if (text3 == path3 && section == path2 && key == path1) { matchesLevel4.Add(x); } } } } }); if (matchesLevel1.Count == 0) { return (null, "no level 1 matches"); } if (matchesLevel1.Count == 1) { return (matchesLevel1, null); } if (matchesLevel2.Count == 0) { return (matchesLevel1, "multiple level 1 matches, no level 2 matches"); } if (matchesLevel2.Count == 1) { return (matchesLevel2, null); } if (matchesLevel3.Count == 0) { return (matchesLevel2, "multiple level 2 matches, no level 3 matches"); } if (matchesLevel3.Count == 1) { return (matchesLevel3, null); } if (matchesLevel4.Count == 0) { return (matchesLevel3, "multiple level 3 matches, no level 4 matches"); } if (matchesLevel4.Count == 1) { return (matchesLevel4, null); } Debug.LogError((object)("AutoConfig: There are multiple config entries with the path \"" + matchesLevel4[0].readablePath + "\"; this should never happen! Please report this as a bug.")); return (matchesLevel4, "multiple level 4 matches"); } } public class AutoConfigContainer { public struct BindSubDictInfo { public object key; public object val; public Type keyType; public int index; } protected internal readonly List bindings = new List(); protected internal virtual AutoConfigUpdateActionTypes defaultEnabledUpdateFlags => AutoConfigUpdateActionTypes.None; public event EventHandler ConfigEntryChanged; public AutoConfigBinding FindConfig(string propName) { return bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == propName && !x.onDict); } public AutoConfigBinding FindConfig(string propName, object dictKey) { return bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == propName && x.onDict && x.boundKey == dictKey); } internal void OnConfigChanged(AutoConfigUpdateActionEventArgs e) { this.ConfigEntryChanged?.Invoke(this, e); Debug.Log((object)$"{e.target.readablePath}: {e.oldValue} > {e.newValue}"); if ((Object)(object)Run.instance != (Object)null && ((Behaviour)Run.instance).isActiveAndEnabled) { if ((e.flags & AutoConfigUpdateActionTypes.InvalidateStats) == AutoConfigUpdateActionTypes.InvalidateStats) { AutoConfigModule.globalStatsDirty = true; } if ((e.flags & AutoConfigUpdateActionTypes.InvalidateDropTable) == AutoConfigUpdateActionTypes.InvalidateDropTable) { AutoConfigModule.globalDropsDirty = true; } } } private string ReplaceTags(string orig, PropertyInfo prop, string categoryName, BindSubDictInfo? subDict = null) { return Regex.Replace(orig, "", delegate(Match m) { string value = m.Groups[0].Value; string[] array = Regex.Split(value.Substring(1, value.Length - 1 - 1), "(?= 2) { string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + ": malformed string param \"" + m.Value + "\" "; switch (array[1]) { case "Prop": { if (array.Length < 3) { AdmiralPlugin._logger.LogWarning((object)(text + "(not enough params for Prop tag).")); return m.Value; } PropertyInfo property2 = prop.DeclaringType.GetProperty(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property2 == null) { AdmiralPlugin._logger.LogWarning((object)(text + "(could not find Prop \"" + array[2] + "\").")); return m.Value; } return property2.GetValue(this).ToString(); } case "Field": { if (array.Length < 3) { AdmiralPlugin._logger.LogWarning((object)(text + "(not enough params for Field tag).")); return m.Value; } FieldInfo field2 = prop.DeclaringType.GetField(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null) { AdmiralPlugin._logger.LogWarning((object)(text + "(could not find Field \"" + array[2] + "\").")); return m.Value; } return field2.GetValue(this).ToString(); } case "DictKey": if (!subDict.HasValue) { AdmiralPlugin._logger.LogWarning((object)(text + "(DictKey tag used on non-BindDict).")); return m.Value; } return subDict.Value.key.ToString(); case "DictInd": if (!subDict.HasValue) { AdmiralPlugin._logger.LogWarning((object)(text + "(DictInd tag used on non-BindDict).")); return m.Value; } return subDict.Value.index.ToString(); case "DictKeyProp": { if (!subDict.HasValue) { AdmiralPlugin._logger.LogWarning((object)(text + "(DictKeyProp tag used on non-BindDict).")); return m.Value; } if (array.Length < 3) { AdmiralPlugin._logger.LogWarning((object)(text + "(not enough params for DictKeyProp tag).")); return m.Value; } PropertyInfo property = subDict.Value.key.GetType().GetProperty(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null) { AdmiralPlugin._logger.LogWarning((object)(text + "(could not find DictKeyProp \"" + array[2] + "\").")); return m.Value; } return property.GetValue(subDict.Value.key).ToString(); } case "DictKeyField": { if (!subDict.HasValue) { AdmiralPlugin._logger.LogWarning((object)(text + "(DictKeyField tag used on non-BindDict).")); return m.Value; } if (array.Length < 3) { AdmiralPlugin._logger.LogWarning((object)(text + "(not enough params for DictKeyField tag).")); return m.Value; } FieldInfo field = subDict.Value.key.GetType().GetField(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { AdmiralPlugin._logger.LogWarning((object)(text + "(could not find DictKeyField \"" + array[2] + "\").")); return m.Value; } return field.GetValue(subDict.Value.key).ToString(); } default: AdmiralPlugin._logger.LogWarning((object)(text + "(unknown tag \"" + array[1] + "\").")); return m.Value; } } return m.Value; }); } public void Bind(PropertyInfo prop, ConfigFile cfl, string modName, string categoryName, AutoConfigAttribute attrib, AutoConfigUpdateActionsAttribute eiattr = null, BindSubDictInfo? subDict = null) { //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06a8: Expected O, but got Unknown //IL_06bd: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Expected O, but got Unknown //IL_06c8: Unknown result type (might be due to invalid IL or missing references) //IL_06d2: Expected O, but got Unknown string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + " failed: "; if (!subDict.HasValue) { if (bindings.Exists((AutoConfigBinding x) => x.boundProperty == prop)) { AdmiralPlugin._logger.LogError((object)(text + "this property has already been bound.")); return; } if ((attrib.flags & AutoConfigFlags.BindDict) == AutoConfigFlags.BindDict) { if (!prop.PropertyType.GetInterfaces().Any((Type i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<, >))) { AdmiralPlugin._logger.LogError((object)(text + "BindDict flag cannot be used on property types which don't implement IDictionary.")); return; } Type type = prop.PropertyType.GetGenericArguments()[1]; if (attrib.avb != null && attrib.avbType != type) { AdmiralPlugin._logger.LogError((object)(text + "dict value and AcceptableValue types must match (received " + type.Name + " and " + attrib.avbType.Name + ").")); return; } if (!TomlTypeConverter.CanConvert(type)) { AdmiralPlugin._logger.LogError((object)(text + "dict value type cannot be converted by BepInEx.Configuration.TomlTypeConverter (received " + type.Name + ").")); return; } IDictionary dictionary = (IDictionary)prop.GetValue(this, null); int num = 0; List list = (from object k in dictionary.Keys select (k)).ToList(); if (list.Count == 0) { AdmiralPlugin._logger.LogError((object)(text + "BindDict was used on an empty dictionary. All intended keys must be present at time of binding and cannot be added afterwards.")); } { foreach (object item in list) { Bind(prop, cfl, modName, categoryName, attrib, eiattr, new BindSubDictInfo { key = item, val = dictionary[item], keyType = type, index = num }); num++; } return; } } } if (!subDict.HasValue) { if (attrib.avb != null && attrib.avbType != prop.PropertyType) { AdmiralPlugin._logger.LogError((object)(text + "property and AcceptableValue types must match (received " + prop.PropertyType.Name + " and " + attrib.avbType.Name + ").")); return; } if (!TomlTypeConverter.CanConvert(prop.PropertyType)) { AdmiralPlugin._logger.LogError((object)(text + "property type cannot be converted by BepInEx.Configuration.TomlTypeConverter (received " + prop.PropertyType.Name + ").")); return; } } object obj2 = (subDict.HasValue ? prop.GetValue(this) : this); IDictionary dictionary2 = (subDict.HasValue ? ((IDictionary)obj2) : null); MethodInfo methodInfo = (subDict.HasValue ? dictionary2.GetType().GetProperty("Item").GetGetMethod(nonPublic: true) : (prop.GetGetMethod(nonPublic: true) ?? prop.DeclaringType.GetProperty(prop.Name)?.GetGetMethod(nonPublic: true))); MethodInfo methodInfo2 = (subDict.HasValue ? dictionary2.GetType().GetProperty("Item").GetSetMethod(nonPublic: true) : (prop.GetSetMethod(nonPublic: true) ?? prop.DeclaringType.GetProperty(prop.Name)?.GetSetMethod(nonPublic: true))); Type type2 = (subDict.HasValue ? subDict.Value.keyType : prop.PropertyType); if (methodInfo == null || methodInfo2 == null) { AdmiralPlugin._logger.LogError((object)(text + "property (or IDictionary Item property, if using BindDict flag) must have both a getter and a setter.")); return; } string name = attrib.name; if (name != null) { name = ReplaceTags(name, prop, categoryName, subDict); } else { object arg = char.ToUpperInvariant(prop.Name[0]); string name2 = prop.Name; name = string.Format("{0}{1}{2}", arg, name2.Substring(1, name2.Length - 1), subDict.HasValue ? (":" + subDict.Value.index) : ""); } string desc = attrib.desc; desc = ((desc == null) ? ("Automatically generated from a C# " + (subDict.HasValue ? "dictionary " : "") + "property.") : ReplaceTags(desc, prop, categoryName, subDict)); MethodInfo methodInfo3 = typeof(ConfigFile).GetMethods().First((MethodInfo x) => x.Name == "Bind" && x.GetParameters().Length == 3 && x.GetParameters()[0].ParameterType == typeof(ConfigDefinition) && x.GetParameters()[2].ParameterType == typeof(ConfigDescription)).MakeGenericMethod(type2); object obj3 = (subDict.HasValue ? subDict.Value.val : prop.GetValue(this)); bool flag = (attrib.flags & AutoConfigFlags.DeferForever) == AutoConfigFlags.DeferForever; bool flag2 = (attrib.flags & AutoConfigFlags.DeferUntilEndGame) == AutoConfigFlags.DeferUntilEndGame; bool flag3 = (attrib.flags & AutoConfigFlags.DeferUntilNextStage) == AutoConfigFlags.DeferUntilNextStage; bool flag4 = (attrib.flags & AutoConfigFlags.PreventConCmd) != AutoConfigFlags.PreventConCmd; if (flag) { desc += "\nThis setting cannot be changed while the game is running."; } ConfigEntryBase cfe = (ConfigEntryBase)methodInfo3.Invoke(cfl, new object[3] { (object)new ConfigDefinition(categoryName, name), obj3, (object)new ConfigDescription(desc, attrib.avb, Array.Empty()) }); AutoConfigBinding newBinding = new AutoConfigBinding { boundProperty = prop, allowConCmd = (flag4 && !flag && !flag2), deferType = (flag ? AutoConfigBinding.DeferType.NeverAutoUpdate : (flag2 ? AutoConfigBinding.DeferType.WaitForRunEnd : (flag3 ? AutoConfigBinding.DeferType.WaitForNextStage : AutoConfigBinding.DeferType.UpdateImmediately))), configEntry = cfe, modName = modName, owner = this, propGetter = methodInfo, propSetter = methodInfo2, propType = type2, onDict = subDict.HasValue, boundKey = (subDict.HasValue ? subDict.Value.key : null), updateEventAttribute = eiattr, cachedValue = obj3, target = obj2 }; bindings.Add(newBinding); if (!flag) { Type type3 = typeof(ConfigEntry<>).MakeGenericType(type2); EventInfo @event = type3.GetEvent("SettingChanged"); Action action = delegate { newBinding.UpdateProperty(cfe.BoxedValue); }; ParameterExpression[] array = (from p in @event.EventHandlerType.GetMethod("Invoke").GetParameters() select Expression.Parameter(p.ParameterType)).ToArray(); Delegate handler = Expression.Lambda(@event.EventHandlerType, Expression.Call(Expression.Constant(action), action.GetType().GetMethod("Invoke"), array[0], array[1]), array).Compile(); @event.AddEventHandler(cfe, handler); } if ((attrib.flags & AutoConfigFlags.NoInitialRead) != AutoConfigFlags.NoInitialRead) { methodInfo2.Invoke(obj2, (!subDict.HasValue) ? new object[1] { cfe.BoxedValue } : new object[2] { subDict.Value.key, cfe.BoxedValue }); newBinding.cachedValue = cfe.BoxedValue; } BindRoO(cfe, prop, type2, categoryName, name, desc, flag, flag2 || flag); } public void BindRoO(AutoConfigBinding bind, params BaseAutoConfigRoOAttribute[] entryRoOAttributes) { BindRoO(bind.configEntry, bind.boundProperty, bind.propType, bind.configEntry.Definition.Section, bind.configEntry.Definition.Key, bind.configEntry.Description.Description, bind.deferType >= AutoConfigBinding.DeferType.NeverAutoUpdate, bind.deferType >= AutoConfigBinding.DeferType.WaitForRunEnd, entryRoOAttributes); } public void BindRoO(ConfigEntryBase cfe, PropertyInfo prop, Type propType, string categoryName, string cfgName, string cfgDesc, bool deferForever, bool deferRun, params BaseAutoConfigRoOAttribute[] entryRoOAttributes) { if (!Compat_RiskOfOptions.enabled) { return; } string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + " could not apply Risk of Options compat: "; AutoConfigRoOInfoOverridesAttribute customAttribute = GetType().GetCustomAttribute(); AutoConfigRoOInfoOverridesAttribute customAttribute2 = prop.GetCustomAttribute(); if (entryRoOAttributes.Length == 0) { return; } if ((from x in entryRoOAttributes group x by x.GetType()).Any((IGrouping x) => x.Count() > 1)) { AdmiralPlugin._logger.LogWarning((object)("AutoConfigContainer.BindRoO on property " + prop.Name + " in category " + categoryName + " has multiple RoO options of the same type")); } string text2 = null; string text3 = null; bool flag = false; if (customAttribute != null) { text2 = customAttribute.modGuid; text3 = customAttribute.modName; flag = true; } else { Assembly assembly = Assembly.GetAssembly(GetType()); Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } Type[] array = types; foreach (Type element in array) { BepInPlugin customAttribute3 = ((MemberInfo)element).GetCustomAttribute(); if (customAttribute3 != null) { text2 = customAttribute3.GUID; text3 = customAttribute3.Name; flag = true; break; } } } if (!flag) { AdmiralPlugin._logger.LogError((object)(text + "could not find mod info. Declaring type must be in an assembly with a BepInPlugin, or have an AutoConfigContainerRoOInfoAttribute on it.")); return; } Compat_RiskOfOptions.OptionIdentityStrings optionIdentityStrings = default(Compat_RiskOfOptions.OptionIdentityStrings); optionIdentityStrings.category = customAttribute2?.categoryName ?? customAttribute?.categoryName ?? categoryName; optionIdentityStrings.name = customAttribute2?.entryName ?? customAttribute?.entryName ?? cfgName; optionIdentityStrings.description = cfgDesc; optionIdentityStrings.modGuid = customAttribute2?.modGuid ?? text2; optionIdentityStrings.modName = customAttribute2?.modName ?? text3; Compat_RiskOfOptions.OptionIdentityStrings identStrings = optionIdentityStrings; foreach (BaseAutoConfigRoOAttribute baseAutoConfigRoOAttribute in entryRoOAttributes) { if ((baseAutoConfigRoOAttribute.requiredType == typeof(Enum)) ? (!propType.IsEnum) : (propType != baseAutoConfigRoOAttribute.requiredType)) { AdmiralPlugin._logger.LogError((object)(text + baseAutoConfigRoOAttribute.GetType().Name + " may only be applied to " + baseAutoConfigRoOAttribute.requiredType.Name + " properties (got " + propType.Name + ").")); } else { baseAutoConfigRoOAttribute.Apply(cfe, identStrings, deferForever, () => (deferRun && Object.op_Implicit((Object)(object)Run.instance)) ? true : false); } } } internal void BindRoO(ConfigEntryBase cfe, PropertyInfo prop, Type propType, string categoryName, string cfgName, string cfgDesc, bool deferForever, bool deferRun) { if (Compat_RiskOfOptions.enabled) { BindRoO(cfe, prop, propType, categoryName, cfgName, cfgDesc, deferForever, deferRun, prop.GetCustomAttributes().ToArray()); } } public void BindAll(ConfigFile cfl, string modName, string categoryName) { PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { AutoConfigAttribute customAttribute = propertyInfo.GetCustomAttribute(inherit: true); if (customAttribute != null) { Bind(propertyInfo, cfl, modName, categoryName, customAttribute, propertyInfo.GetCustomAttribute(inherit: true)); } } } } internal class AutoConfigModule : Module { internal static bool globalStatsDirty; internal static bool globalDropsDirty; internal static bool globalLanguageDirty; public override bool managedEnable => false; public override void SetupConfig() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.SetupConfig(); NetworkManagerSystem.Disconnect += new hook_Disconnect(On_GNMDisconnect); SceneManager.sceneLoaded += Evt_USMSceneLoaded; } internal static void Update() { if (!((Object)(object)Run.instance != (Object)null) || !((Behaviour)Run.instance).isActiveAndEnabled) { globalStatsDirty = false; globalDropsDirty = false; } else { if (globalStatsDirty) { globalStatsDirty = false; CharacterMaster.readOnlyInstancesList.Where((CharacterMaster x) => x.hasBody && x.GetBody().healthComponent.alive).ToList().ForEach(delegate(CharacterMaster cm) { if (cm.hasBody) { cm.GetBody().RecalculateStats(); } }); } if (globalDropsDirty) { globalDropsDirty = false; Run.instance.OnRuleBookUpdated(Run.instance.networkRuleBookComponent); Run.instance.BuildDropTable(); } } if (globalLanguageDirty) { globalLanguageDirty = false; Language.SetCurrentLanguage(Language.currentLanguageName); } } internal static void On_GNMDisconnect(orig_Disconnect orig, NetworkManagerSystem self) { orig.Invoke(self); AutoConfigBinding.CleanupDirty(isRunEnd: true); } internal static void Evt_USMSceneLoaded(Scene scene, LoadSceneMode mode) { AutoConfigBinding.CleanupDirty(isRunEnd: false); } } [Flags] public enum AutoConfigFlags { None = 0, AVIsList = 1, DeferUntilNextStage = 2, DeferUntilEndGame = 4, DeferForever = 8, PreventConCmd = 0x10, NoInitialRead = 0x20, BindDict = 0x40 } [Flags] public enum AutoConfigUpdateActionTypes { None = 0, InvalidateLanguage = 1, InvalidateModel = 2, InvalidateStats = 4, InvalidateDropTable = 8 } public class AutoConfigUpdateActionEventArgs : EventArgs { public AutoConfigUpdateActionTypes flags; public object oldValue; public object newValue; public AutoConfigBinding target; public bool silent; } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigUpdateActionsAttribute : Attribute { public readonly AutoConfigUpdateActionTypes flags; public readonly bool ignoreDefault; public AutoConfigUpdateActionsAttribute(AutoConfigUpdateActionTypes flags, bool ignoreDefault = false) { this.flags = flags; this.ignoreDefault = ignoreDefault; } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigAttribute : Attribute { public readonly string name = null; public readonly string desc = null; public readonly AcceptableValueBase avb = null; public readonly Type avbType = null; public readonly AutoConfigFlags flags; public AutoConfigAttribute(string name, string desc, AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues) : this(desc, flags, acceptableValues) { this.name = name; } public AutoConfigAttribute(string desc, AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues) : this(flags, acceptableValues) { this.desc = desc; } public AutoConfigAttribute(AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown if (acceptableValues.Length != 0) { bool flag = (flags & AutoConfigFlags.AVIsList) == AutoConfigFlags.AVIsList; if (!flag && acceptableValues.Length != 2) { throw new ArgumentException("Range mode for acceptableValues (flag AVIsList not set) requires either 0 or 2 params; received " + acceptableValues.Length + ".\nThe description provided was: \"" + desc + "\"."); } Type type = acceptableValues[0].GetType(); for (int i = 1; i < acceptableValues.Length; i++) { if (type != acceptableValues[i].GetType()) { throw new ArgumentException("Types of all acceptableValues must match"); } } avb = (AcceptableValueBase)Activator.CreateInstance(flag ? typeof(AcceptableValueList<>).MakeGenericType(type) : typeof(AcceptableValueRange<>).MakeGenericType(type), acceptableValues); avbType = type; } this.flags = flags; } } public abstract class BaseAutoConfigRoOAttribute : Attribute { public string nameOverride; public string catOverride; public abstract Type requiredType { get; } public BaseAutoConfigRoOAttribute(string nameOverride = null, string catOverride = null) { this.nameOverride = nameOverride; this.catOverride = catOverride; } public abstract void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate); } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOSliderAttribute : BaseAutoConfigRoOAttribute { public string format; public float min; public float max; public override Type requiredType => typeof(float); public AutoConfigRoOSliderAttribute(string format, float min, float max, string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { this.format = format; this.min = min; this.max = max; } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_Slider((ConfigEntry)(object)cfe, identStrings, min, max, format, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOStepSliderAttribute : BaseAutoConfigRoOAttribute { public string format; public float min; public float max; public float step; public override Type requiredType => typeof(float); public AutoConfigRoOStepSliderAttribute(string format, float min, float max, float step, string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { this.format = format; this.min = min; this.max = max; this.step = step; } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_StepSlider((ConfigEntry)(object)cfe, identStrings, min, max, step, format, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOIntSliderAttribute : BaseAutoConfigRoOAttribute { public string format; public int min; public int max; public override Type requiredType => typeof(int); public AutoConfigRoOIntSliderAttribute(string format, int min, int max, string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { this.format = format; this.min = min; this.max = max; } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_IntSlider((ConfigEntry)(object)cfe, identStrings, min, max, format, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOChoiceAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(Enum); public AutoConfigRoOChoiceAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_Choice(cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOKeybindAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(KeyboardShortcut); public AutoConfigRoOKeybindAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_Keybind((ConfigEntry)(object)cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOCheckboxAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(bool); public AutoConfigRoOCheckboxAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_CheckBox((ConfigEntry)(object)cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOStringAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(string); public AutoConfigRoOStringAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_String((ConfigEntry)(object)cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOInfoOverridesAttribute : Attribute { public string modGuid; public string modName; public string categoryName; public string entryName; public AutoConfigRoOInfoOverridesAttribute(string guid, string name, string cat = null, string ent = null) { modGuid = guid; modName = name; categoryName = cat; entryName = ent; } public AutoConfigRoOInfoOverridesAttribute(Type ownerPluginType, string cat = null, string ent = null) { BepInPlugin customAttribute = ((MemberInfo)ownerPluginType).GetCustomAttribute(); if (customAttribute == null) { AdmiralPlugin._logger.LogError((object)("AutoConfigContainerRoOInfoAttribute received an invalid type " + ownerPluginType.Name + " with no BepInPluginAttribute")); return; } modGuid = customAttribute.GUID; modName = customAttribute.Name; categoryName = cat; entryName = ent; } } public static class AutoConfigPresetExtensions { public static void ApplyPreset(this AutoConfigContainer container, string name) { HashSet hashSet = new HashSet(); foreach (AutoConfigBinding binding in container.bindings) { IEnumerable source = binding.boundProperty.GetCustomAttributes(typeof(AutoConfigPresetAttribute), inherit: true).Cast(); AutoConfigPresetAttribute autoConfigPresetAttribute = source.FirstOrDefault((AutoConfigPresetAttribute p) => p.presetName == name); if (autoConfigPresetAttribute != null) { binding.configEntry.BoxedValue = autoConfigPresetAttribute.boxedValue; if (!binding.configEntry.ConfigFile.SaveOnConfigSet) { hashSet.Add(binding.configEntry.ConfigFile); } } } foreach (ConfigFile item in hashSet) { item.Save(); } } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class AutoConfigPresetAttribute : Attribute { public readonly string presetName; public readonly object boxedValue; public AutoConfigPresetAttribute(string name, object value) { presetName = name; boxedValue = value; } } public abstract class Module : Module where T : Module { public static T instance { get; private set; } protected Module() { if (instance != null) { throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting Module was instantiated twice"); } instance = this as T; } } public abstract class Module : AutoConfigContainer { public struct ModInfo { public string displayName; public string longIdentifier; public string shortIdentifier; public ConfigFile mainConfigFile; } private static readonly FilingDictionary _allModules = new FilingDictionary(); public static readonly ReadOnlyFilingDictionary allModules = _allModules.AsReadOnly(); public readonly string name; protected readonly List languageOverlays = new List(); protected readonly List permanentLanguageOverlays = new List(); protected readonly Dictionary genericLanguageTokens = new Dictionary(); protected readonly Dictionary> specificLanguageTokens = new Dictionary>(); protected readonly Dictionary permanentGenericLanguageTokens = new Dictionary(); protected readonly Dictionary> permanentSpecificLanguageTokens = new Dictionary>(); public bool enabled { get; protected internal set; } = true; public virtual bool managedEnable => true; public virtual bool managedEnableRoO => true; public virtual string enabledConfigDescription => null; public virtual AutoConfigFlags enabledConfigFlags => AutoConfigFlags.None; public virtual AutoConfigUpdateActionTypes enabledConfigUpdateActionTypes => AutoConfigUpdateActionTypes.InvalidateLanguage; public bool languageInstalled { get; private set; } = false; public bool permanentLanguageInstalled { get; private set; } = false; public Xoroshiro128Plus rng { get; internal set; } public ModInfo modInfo { get; private set; } public virtual string configCategoryPrefix => "Modules."; internal static void SetupModuleClass() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown Run.Start += new hook_Start(On_RunStart); Language.SetCurrentLanguage += new hook_SetCurrentLanguage(Language_SetCurrentLanguage); } private static void On_RunStart(orig_Start orig, Run self) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown orig.Invoke(self); if (!NetworkServer.active) { return; } Xoroshiro128Plus val = new Xoroshiro128Plus(self.seed); foreach (Module allModule in _allModules) { allModule.rng = new Xoroshiro128Plus(val.nextUlong); } } private static void Language_SetCurrentLanguage(orig_SetCurrentLanguage orig, string newCurrentLanguageName) { orig.Invoke(newCurrentLanguageName); foreach (Module allModule in allModules) { allModule.RefreshPermanentLanguage(); if (allModule.enabled) { if (allModule.languageInstalled) { allModule.UninstallLanguage(); } allModule.InstallLanguage(); } } AutoConfigModule.globalLanguageDirty = false; } public virtual void SetupConfig() { string categoryName = configCategoryPrefix + name; if (managedEnable) { Bind(typeof(Module).GetProperty("enabled"), modInfo.mainConfigFile, modInfo.displayName, categoryName, new AutoConfigAttribute(((enabledConfigDescription != null) ? (enabledConfigDescription + "\n") : "") + "Set to False to disable this module, and as much of its content as can be disabled after initial load. Doing so may cause changes in other modules as well.", enabledConfigFlags), (enabledConfigUpdateActionTypes != 0) ? new AutoConfigUpdateActionsAttribute(enabledConfigUpdateActionTypes) : null); if (managedEnableRoO && Compat_RiskOfOptions.enabled) { AutoConfigBinding bind = bindings.First((AutoConfigBinding x) => x.boundProperty == typeof(Module).GetProperty("enabled")); BindRoO(bind, new AutoConfigRoOCheckboxAttribute()); } } BindAll(modInfo.mainConfigFile, modInfo.displayName, categoryName); base.ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args) { if (args.target.boundProperty.Name == "enabled") { if ((bool)args.newValue) { Install(); } else { Uninstall(); if (languageInstalled) { UninstallLanguage(); } } RefreshPermanentLanguage(); } if (args.flags.HasFlag(AutoConfigUpdateActionTypes.InvalidateLanguage)) { if (enabled) { if (languageInstalled) { UninstallLanguage(); } InstallLanguage(); } RefreshPermanentLanguage(); } }; } public virtual void SetupAttributes() { } public virtual void SetupBehavior() { } public virtual void SetupLate() { } public virtual void Install() { } public virtual void Uninstall() { } public virtual void InstallLanguage() { languageOverlays.Add(LanguageAPI.AddOverlay(genericLanguageTokens)); languageOverlays.Add(LanguageAPI.AddOverlay(specificLanguageTokens)); languageInstalled = true; AutoConfigModule.globalLanguageDirty = true; } public virtual void UninstallLanguage() { foreach (LanguageOverlay languageOverlay in languageOverlays) { languageOverlay.Remove(); } languageOverlays.Clear(); languageInstalled = false; AutoConfigModule.globalLanguageDirty = true; } public virtual void RefreshPermanentLanguage() { if (permanentLanguageInstalled) { foreach (LanguageOverlay permanentLanguageOverlay in permanentLanguageOverlays) { permanentLanguageOverlay.Remove(); } } permanentLanguageOverlays.Clear(); permanentLanguageOverlays.Add(LanguageAPI.AddOverlay(permanentGenericLanguageTokens)); permanentLanguageOverlays.Add(LanguageAPI.AddOverlay(permanentSpecificLanguageTokens)); AutoConfigModule.globalLanguageDirty = true; } public static FilingDictionary InitDirect(ModInfo modInfo) where T : Module { return InitAll(modInfo, Assembly.GetCallingAssembly(), (Type t) => (!t.BaseType.IsGenericType) ? (t.BaseType == typeof(T)) : (t.BaseType.GenericTypeArguments[0] == t && t.BaseType.BaseType == typeof(T))); } public static FilingDictionary InitAll(ModInfo modInfo, Func extraTypeChecks = null) where T : Module { return InitAll(modInfo, Assembly.GetCallingAssembly(), extraTypeChecks); } private static FilingDictionary InitAll(ModInfo modInfo, Assembly callingAssembly, Func extraTypeChecks) where T : Module { FilingDictionary filingDictionary = new FilingDictionary(); foreach (Type item in from t in callingAssembly.GetTypes() where t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(T)) && (extraTypeChecks?.Invoke(t) ?? true) select t) { T val = (T)Activator.CreateInstance(item, nonPublic: true); val.modInfo = modInfo; filingDictionary.Add(val); } return filingDictionary; } public static FilingDictionary InitModules(ModInfo modInfo) { return InitAll(modInfo, Assembly.GetCallingAssembly(), (Type t) => (!t.BaseType.IsGenericType) ? (t.BaseType == typeof(Module)) : (t.BaseType.GenericTypeArguments[0] == t && t.BaseType.BaseType == typeof(Module))); } public static void SetupAll_PluginAwake(IEnumerable modulesToSetup) { foreach (Module item in modulesToSetup) { item.SetupConfig(); } foreach (Module item2 in modulesToSetup) { item2.SetupAttributes(); } foreach (Module item3 in modulesToSetup) { item3.SetupBehavior(); } } public static void SetupAll_PluginStart(IEnumerable modulesToSetup, bool installUnmanaged = false) { foreach (Module item in modulesToSetup) { item.SetupLate(); } foreach (Module item2 in modulesToSetup) { if ((installUnmanaged || item2.managedEnable) && item2.enabled) { item2.Install(); } } } protected Module() { name = GetType().Name; _allModules.Add(this); } } public class BeaconRebalance : Module { internal GameObject muzzleFlashPrefab; private bool isNormalRechargeRunning = false; [AutoConfigRoOSlider("{0:P0}", 0f, 1f, null, null)] [AutoConfig("Fractional influence of cooldown reduction, e.g. Alien Head and unknown cooldown sources from other mods, on temporary beacons (0 = no effect, 1 = full effect).", AutoConfigFlags.DeferUntilNextStage, new object[] { 0f, 1f })] public float beaconCDRInfluence { get; private set; } = 0.5f; [AutoConfigRoOSlider("{0:P0}", 0f, 1f, null, null)] [AutoConfig("Fractional influence of restock, e.g. Bandolier, on temporary beacons (0 = no effect, 1 = full effect).", AutoConfigFlags.DeferUntilNextStage, new object[] { 0f, 1f })] public float beaconRestockInfluence { get; private set; } = 0.5f; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If false, the original beacon skills will not be replaced; temporary beacons will instead be provided as alternates.", AutoConfigFlags.DeferForever, new object[] { })] public bool removeOriginals { get; private set; } = true; public override string enabledConfigDescription => "Changes all Beacon skills to have cooldown and lifetime, and replaces some variants which are incompatible with this model."; public override AutoConfigUpdateActionTypes enabledConfigUpdateActionTypes => AutoConfigUpdateActionTypes.InvalidateLanguage; public override AutoConfigFlags enabledConfigFlags => AutoConfigFlags.DeferUntilNextStage; public override void SetupAttributes() { base.SetupAttributes(); muzzleFlashPrefab = LegacyResourcesAPI.Load("prefabs/effects/muzzleflashes/MuzzleflashSupplyDrop, Healing"); } public override void InstallLanguage() { base.InstallLanguage(); languageOverlays.Add(LanguageAPI.AddOverlay("CAPTAIN_SPECIAL_DESCRIPTION", "Request one of two temporary Supply Beacons. Both beacons have independent cooldowns.")); } public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown base.Install(); CaptainSupplyDropController.UpdateSkillOverrides += new Manipulator(IL_CSDCUpdateSkillOverrides); CaptainSupplyDropController.SetSkillOverride += new hook_SetSkillOverride(On_CSDCSetSkillOverride); GenericSkill.CalculateFinalRechargeInterval += new hook_CalculateFinalRechargeInterval(On_GSCalculateFinalRechargeInterval); GenericSkill.RecalculateMaxStock += new hook_RecalculateMaxStock(On_GSRecalculateMaxStock); GenericSkill.AddOneStock += new hook_AddOneStock(On_GSAddOneStock); GenericSkill.RunRecharge += new hook_RunRecharge(On_GSRunRecharge); GenericSkill.FixedUpdate += new hook_FixedUpdate(On_GSFixedUpdate); Module.instance.Install(); Module.instance.Install(); Module.instance.Install(); Module.instance.Install(); } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown base.Uninstall(); CaptainSupplyDropController.UpdateSkillOverrides -= new Manipulator(IL_CSDCUpdateSkillOverrides); CaptainSupplyDropController.SetSkillOverride -= new hook_SetSkillOverride(On_CSDCSetSkillOverride); GenericSkill.CalculateFinalRechargeInterval -= new hook_CalculateFinalRechargeInterval(On_GSCalculateFinalRechargeInterval); GenericSkill.RecalculateMaxStock -= new hook_RecalculateMaxStock(On_GSRecalculateMaxStock); GenericSkill.AddOneStock -= new hook_AddOneStock(On_GSAddOneStock); GenericSkill.RunRecharge -= new hook_RunRecharge(On_GSRunRecharge); GenericSkill.FixedUpdate -= new hook_FixedUpdate(On_GSFixedUpdate); Module.instance.Uninstall(); Module.instance.Uninstall(); Module.instance.Uninstall(); Module.instance.Uninstall(); } private bool SkillIsTemporaryBeacon(SkillDef skillDef) { return (Object)(object)skillDef == (Object)(object)Module.instance.skillDef || (Object)(object)skillDef == (Object)(object)Module.instance.skillDef || (Object)(object)skillDef == (Object)(object)Module.instance.skillDef || (Object)(object)skillDef == (Object)(object)Module.instance.skillDef; } private bool SkillIsTemporaryBeacon(GenericSkill skill) { return SkillIsTemporaryBeacon(skill.skillDef); } private void On_GSFixedUpdate(orig_FixedUpdate orig, GenericSkill self) { isNormalRechargeRunning = true; orig.Invoke(self); isNormalRechargeRunning = false; } private void On_GSRunRecharge(orig_RunRecharge orig, GenericSkill self, float dt) { if (SkillIsTemporaryBeacon(self) && !isNormalRechargeRunning) { dt *= beaconCDRInfluence; } orig.Invoke(self, dt); } private void On_GSAddOneStock(orig_AddOneStock orig, GenericSkill self) { if (SkillIsTemporaryBeacon(self)) { self.rechargeStopwatch += self.finalRechargeInterval * beaconRestockInfluence; } else { orig.Invoke(self); } } private void On_GSRecalculateMaxStock(orig_RecalculateMaxStock orig, GenericSkill self) { orig.Invoke(self); if (SkillIsTemporaryBeacon(self)) { self.maxStock = 1; } } private float On_GSCalculateFinalRechargeInterval(orig_CalculateFinalRechargeInterval orig, GenericSkill self) { float num = orig.Invoke(self); if (SkillIsTemporaryBeacon(self)) { return self.baseRechargeInterval * (1f - beaconCDRInfluence) + num * beaconCDRInfluence; } return num; } private void On_CSDCSetSkillOverride(orig_SetSkillOverride orig, CaptainSupplyDropController self, ref SkillDef currentSkillDef, SkillDef newSkillDef, GenericSkill component) { if (!SkillIsTemporaryBeacon(currentSkillDef)) { orig.Invoke(self, ref currentSkillDef, newSkillDef, component); } } private void IL_CSDCUpdateSkillOverrides(ILContext il) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown ILCursor val = new ILCursor(il); int maskLocIndex = -1; int num = default(int); ILLabel val2 = default(ILLabel); if (val.TryGotoNext(new Func[5] { (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref maskLocIndex), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, maskLocIndex), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "authorityEnabledSkillsMask"), (Instruction x) => ILPatternMatchingExt.MatchBeq(x, ref val2) })) { val.Index = 0; val.GotoNext(new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchStloc(x, maskLocIndex) }); val.EmitDelegate>((Func)((byte orig) => 3)); } else { AdmiralPlugin._logger.LogError((object)"BeaconRebalance/CSDCUpdateSkillOverrides: Failed to apply IL patch (target instructions not found)"); } } } public class CancelOrbitalSkills : Module { public override string enabledConfigDescription => "Allows orbital skills to be cancelled by reactivating the skill."; public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.Install(); GenericSkill.ExecuteIfReady += new hook_ExecuteIfReady(GenericSkill_ExecuteIfReady); } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.Uninstall(); GenericSkill.ExecuteIfReady -= new hook_ExecuteIfReady(GenericSkill_ExecuteIfReady); } private bool GenericSkill_ExecuteIfReady(orig_ExecuteIfReady orig, GenericSkill self) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) bool flag = orig.Invoke(self); if (flag || !Object.op_Implicit((Object)(object)self.stateMachine) || self.stateMachine.HasPendingState()) { return flag; } Type type = ((object)self.stateMachine.state).GetType(); SerializableEntityStateType activationState = self.activationState; if (type == ((SerializableEntityStateType)(ref activationState)).stateType && (self.stateMachine.state is SetupAirstrike || self.stateMachine.state is SetupSupplyDrop)) { self.stateMachine.SetNextStateToMain(); } return false; } } public class CatalyzerDartSkill : Module { public class MalevolentCleanseOnHit : MonoBehaviour { } internal UnlockableDef unlockable; internal SkillDef skillDef; internal GameObject projectilePrefab; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Cooldown of Catalyzer Dart.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillRecharge { get; private set; } = 8f; [AutoConfigRoOSlider("{0:P0}", 0f, 10f, null, null)] [AutoConfig("Fraction of remaining DoT damage dealt by malevolent cleanses.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float evilCleanseDoTDamage { get; private set; } = 3f; [AutoConfigRoOSlider("{0:P0}", 0f, 20f, null, null)] [AutoConfig("Fraction of base damage dealt per non-DoT debuff by malevolent cleanses.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float evilCleanseNonDoTDamage { get; private set; } = 5f; public override string enabledConfigDescription => "Adds the Catalyzer Dart secondary skill variant."; public override AutoConfigFlags enabledConfigFlags => AutoConfigFlags.DeferForever; public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); projectilePrefab = CommonCode.ModifyVanillaPrefab("RoR2/Base/Captain/CaptainTazer.prefab", "CaptainCatalyzerProjectile", shouldNetwork: true, delegate(GameObject projPfbPfb) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) projPfbPfb.GetComponent().damageType = DamageTypeCombo.op_Implicit((DamageType)0); ((ProjectileExplosion)projPfbPfb.GetComponent()).blastRadius = 1f; projPfbPfb.AddComponent(); return projPfbPfb; }); ContentAddition.AddProjectile(projectilePrefab); string text = "ADMIRAL_CATALYZER_SKILL_NAME"; string text2 = "ADMIRAL_CATALYZER_SKILL_DESC"; string text3 = "Catalyzer Dart"; LanguageAPI.Add(text, text3); LanguageAPI.Add(text2, "Fire a fast dart which catalyzes all debuffs, converting them to damage: 300% of the remaining total for DoTs, 1x500% otherwise."); skillDef = ScriptableObject.CreateInstance(); skillDef.activationStateMachineName = "Weapon"; skillDef.activationState = activationState; skillDef.interruptPriority = (InterruptPriority)1; skillDef.baseRechargeInterval = skillRecharge; skillDef.baseMaxStock = 1; skillDef.rechargeStock = 1; skillDef.beginSkillCooldownOnSkillEnd = false; skillDef.requiredStock = 1; skillDef.stockToConsume = 1; skillDef.isCombatSkill = true; skillDef.cancelSprintingOnActivation = true; skillDef.canceledFromSprinting = false; skillDef.mustKeyPress = false; skillDef.fullRestockOnAssign = true; skillDef.dontAllowPastMaxStocks = false; skillDef.skillName = text3; skillDef.skillNameToken = text; skillDef.skillDescriptionToken = text2; skillDef.icon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralCatalyzerSkill.png"); ContentAddition.AddSkillDef(skillDef); string text4 = "ACHIEVEMENT_ADMIRAL_" + name.ToUpper(CultureInfo.InvariantCulture) + "_NAME"; string text5 = "ACHIEVEMENT_ADMIRAL_" + name.ToUpper(CultureInfo.InvariantCulture) + "_DESCRIPTION"; unlockable = ScriptableObject.CreateInstance(); unlockable.cachedName = "Admiral_" + name + "Unlockable"; unlockable.sortScore = 200; unlockable.achievementIcon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralCatalyzerSkill.png"); ContentAddition.AddUnlockableDef(unlockable); LanguageAPI.Add(text4, "Captain: Hoist By Their Own Petard"); LanguageAPI.Add(text5, "As Captain, kill 6 other enemies by Shocking the same one."); } public override void Install() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown base.Install(); LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSecondarySkillFamily").AddVariant(skillDef, unlockable); GlobalEventManager.onServerDamageDealt += GlobalEventManager_onServerDamageDealt; FireTazer.Fire += new hook_Fire(FireTazer_Fire); } public override void Uninstall() { base.Uninstall(); LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSecondarySkillFamily").RemoveVariant(skillDef); } private void FireTazer_Fire(orig_Fire orig, FireTazer self) { if (!(self is EntStateFireCatalyzer)) { orig.Invoke(self); return; } GameObject val = FireTazer.projectilePrefab; FireTazer.projectilePrefab = projectilePrefab; orig.Invoke(self); FireTazer.projectilePrefab = val; } private void GlobalEventManager_onServerDamageDealt(DamageReport obj) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)obj.victimBody) || !Object.op_Implicit((Object)(object)obj.damageInfo.inflictor) || !Object.op_Implicit((Object)(object)obj.damageInfo.inflictor.GetComponent())) { return; } int num = 0; for (BuffIndex val = (BuffIndex)0; (int)val < BuffCatalog.buffCount; val = (BuffIndex)(val + 1)) { BuffDef buffDef = BuffCatalog.GetBuffDef(val); if (buffDef.isDebuff) { num += obj.victimBody.GetBuffCount(val); } } EntityStateMachine val2 = ((Component)obj.victimBody).GetComponent()?.targetStateMachine; if (Object.op_Implicit((Object)(object)val2) && (val2.state is FrozenState || val2.state is StunState || val2.state is ShockState)) { num++; } float num2 = 0f; if (DotController.dotControllerLocator.TryGetValue(((Object)((Component)obj.victimBody).gameObject).GetInstanceID(), out var value)) { List dotStackList = value.dotStackList; foreach (DotStack item in dotStackList) { num2 += item.damage * Mathf.Ceil(item.timer / item.dotDef.interval); } } obj.victimBody.healthComponent.TakeDamage(new DamageInfo { attacker = obj.attacker, crit = false, damage = (float)num * obj.attackerBody.damage * evilCleanseNonDoTDamage + num2 * evilCleanseDoTDamage, damageType = DamageTypeCombo.op_Implicit((DamageType)0), procCoefficient = 0f }); CleanseSystem.CleanseBodyServer(obj.victimBody, true, false, true, true, false, false); } } [RegisterAchievement("Admiral_CatalyzerDartSkill", "Admiral_CatalyzerDartSkillUnlockable", "CompleteMainEnding", 3u, null)] public class AdmiralCatalyzerAchievement : BaseAchievement { public override bool wantsBodyCallbacks => true; public override BodyIndex LookUpRequiredBodyIndex() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("CaptainBody"); } public override void OnInstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown ((BaseAchievement)this).OnInstall(); LightningOrb.OnArrival += new hook_OnArrival(LightningOrb_OnArrival); } public override void OnUninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown ((BaseAchievement)this).OnUninstall(); LightningOrb.OnArrival -= new hook_OnArrival(LightningOrb_OnArrival); } private void LightningOrb_OnArrival(orig_OnArrival orig, LightningOrb self) { orig.Invoke(self); if (!(self is ShockedOrb shockedOrb) || self.failedToKill || !Object.op_Implicit((Object)(object)shockedOrb.shockVictim)) { return; } ShockHelper component = shockedOrb.shockVictim.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { component.shockKills++; if (component.shockKills >= 6) { ((BaseAchievement)this).Grant(); } } } } public class EntStateFireCatalyzer : FireTazer { } public class EquipBeacon : Module { public class EntStateCallSupplyDropRejuvenator : CallSupplyDropEquipmentRestock { public override void OnEnter() { ((CallSupplyDropBase)this).supplyDropPrefab = Module.instance.beaconPrefab; ((CallSupplyDropBase)this).muzzleflashEffect = Module.instance.muzzleFlashPrefab; ((CallSupplyDropBase)this).OnEnter(); } } public class EntStateRejuvenatorMainState : EquipmentRestockMainState { public override bool shouldShowEnergy => Module.instance.useInteractable && Module.instance.interactableLimited; public override void OnEnter() { //IL_0042: 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_006e: Unknown result type (might be due to invalid IL or missing references) ((BaseCaptainSupplyDropState)this).OnEnter(); if (NetworkServer.active && !Module.instance.useInteractable) { GameObject val = Object.Instantiate(Module.instance.rejuvWardPrefab, ((EntityState)this).outer.commonComponents.transform.position, ((EntityState)this).outer.commonComponents.transform.rotation); val.GetComponent().teamIndex = ((BaseCaptainSupplyDropState)this).teamFilter.teamIndex; NetworkServer.Spawn(val); } } public override void OnInteractionBegin(Interactor activator) { if (!Object.op_Implicit((Object)(object)activator)) { return; } CharacterBody component = ((Component)activator).GetComponent(); if (Object.op_Implicit((Object)(object)component) && !component.HasBuff(Module.instance.stimmedBuff)) { if (Module.instance.interactableLimited) { ((BaseCaptainSupplyDropState)this).energyComponent.TakeEnergy(base.activationCost); } component.AddTimedBuff(Module.instance.stimmedBuff, Module.instance.skillLifetime); } } public override Interactability GetInteractability(Interactor activator) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!Module.instance.useInteractable) { return (Interactability)0; } if (!Object.op_Implicit((Object)(object)activator)) { return (Interactability)0; } CharacterBody component = ((Component)activator).GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return (Interactability)0; } if (Module.instance.interactableLimited && base.activationCost >= ((BaseCaptainSupplyDropState)this).energyComponent.energy) { return (Interactability)1; } if (component.HasBuff(Module.instance.stimmedBuff)) { return (Interactability)1; } return (Interactability)2; } public override string GetContextString(Interactor activator) { return Language.GetString("ADMIRAL_SUPPLY_REJUVENATOR_CONTEXT"); } } private GameObject rejuvWardPrefab; private SkillFamily skillFamily1; private SkillFamily skillFamily2; private SkillDef origSkillDef; internal SkillDef skillDef; internal GameObject beaconPrefab; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Lifetime of the T.Beacon: Rejuvenator deployable and buff.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillLifetime { get; private set; } = 20f; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Cooldown of T.Beacon: Rejuvenator.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillRecharge { get; private set; } = 50f; [AutoConfigRoOSlider("{0:P0}", 0f, 5f, null, null)] [AutoConfig("Additional fraction of skill recharge rate to provide from the Stimmed buff.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float rechargeRate { get; private set; } = 0.5f; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If true, buff is granted by interacting with the beacon and consuming a once-per-player charge. If false, buff is granted continuously in an area.", AutoConfigFlags.DeferForever, new object[] { })] public bool useInteractable { get; private set; } = true; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If true and UseInteractable is true, only 3 charges will be provided for all players to share. If false, the beacon will have unlimited charges instead, but players who already have the buff will still not be able to stack or renew it (effectively limiting uses to once per player per beacon cooldown).", AutoConfigFlags.DeferForever, new object[] { })] public bool interactableLimited { get; private set; } = false; public override string enabledConfigDescription => "Contains config for the T.Beacon: Resupply submodule of Modules.BeaconRebalance. Replaces Beacon: Equipment."; public override bool managedEnable => false; public BuffDef stimmedBuff { get; private set; } public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0342: 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_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); SerializableEntityStateType mainStateType = ContentAddition.AddEntityState(ref flag); skillFamily1 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop1SkillFamily"); skillFamily2 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop2SkillFamily"); origSkillDef = LegacyResourcesAPI.Load("skilldefs/captainbody/CallSupplyDropEquipmentRestock"); skillDef = SkillUtil.CloneSkillDef(origSkillDef); skillDef.rechargeStock = 1; skillDef.baseRechargeInterval = skillRecharge; skillDef.skillName = "AdmiralSupplyDropRejuvenator"; skillDef.skillNameToken = "ADMIRAL_SUPPLY_REJUVENATOR_NAME"; skillDef.skillDescriptionToken = "ADMIRAL_SUPPLY_REJUVENATOR_DESCRIPTION"; skillDef.activationState = activationState; LanguageAPI.Add(skillDef.skillNameToken, "T.Beacon: Rejuvenator"); LanguageAPI.Add(skillDef.skillDescriptionToken, "Temporary beacon. Buff all nearby allies with +50% skill recharge rate."); ContentAddition.AddSkillDef(skillDef); stimmedBuff = ScriptableObject.CreateInstance(); ((Object)stimmedBuff).name = "Stimmed"; stimmedBuff.iconSprite = LegacyResourcesAPI.Load("textures/itemicons/texSyringeIcon"); stimmedBuff.buffColor = Color.red; stimmedBuff.canStack = false; stimmedBuff.isDebuff = false; ContentAddition.AddBuffDef(stimmedBuff); LanguageAPI.Add("ADMIRAL_SUPPLY_REJUVENATOR_CONTEXT", "Take stim charge"); GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load("prefabs/networkedobjects/captainsupplydrops/CaptainSupplyDrop, EquipmentRestock"), "TempSetup, BeaconPrefabPrefab", false); CaptainBeaconDecayer captainBeaconDecayer = val.AddComponent(); captainBeaconDecayer.lifetime = skillLifetime; if (!useInteractable) { ((Behaviour)val.GetComponent()).enabled = false; ((Behaviour)val.GetComponent()).enabled = true; } val.GetComponent().mainStateType = mainStateType; beaconPrefab = PrefabAPI.InstantiateClone(val, "AdmiralSupplyDrop, Rejuvenator", true); Object.Destroy((Object)(object)val); GameObject val2 = Object.Instantiate(LegacyResourcesAPI.Load("prefabs/networkedobjects/captainsupplydrops/CaptainHealingWard")); ((Behaviour)val2.GetComponent()).enabled = false; Transform val3 = val2.transform.Find("Indicator"); CaptainBeaconDecayer captainBeaconDecayer2 = val2.AddComponent(); captainBeaconDecayer2.lifetime = skillLifetime - CaptainBeaconDecayer.lifetimeDropAdjust; captainBeaconDecayer2.silent = true; BuffWard val4 = val2.AddComponent(); val4.buffDef = stimmedBuff; val4.buffDuration = 1f; val4.radius = 10f; val4.interval = 1f; val4.rangeIndicator = val3; ((Renderer)((Component)val3.Find("IndicatorRing")).GetComponent()).material.SetColor("_TintColor", new Color(1f, 0.5f, 0f, 1f)); ParticleSystemRenderer component = ((Component)val3.Find("HealingSymbols")).GetComponent(); ((Renderer)component).material.SetTexture("_MainTex", LegacyResourcesAPI.Load("textures/bufficons/texBuffTeslaIcon")); ((Renderer)component).material.SetColor("_TintColor", new Color(2f, 0.05f, 0f, 1f)); component.trailMaterial.SetColor("_TintColor", new Color(2f, 0.05f, 0f, 1f)); MainModule main = ((Component)val3.Find("Flashes")).GetComponent().main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.5f, 0.25f, 0f, 1f)); rejuvWardPrefab = PrefabAPI.InstantiateClone(val2, "CaptainRejuvWard", true); Object.Destroy((Object)(object)val2); } public override void Install() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown base.Install(); if (Module.instance.removeOriginals) { skillFamily1.ReplaceVariant(origSkillDef, skillDef); skillFamily2.ReplaceVariant(origSkillDef, skillDef); } else { skillFamily1.AddVariant(skillDef); skillFamily2.AddVariant(skillDef); } SkillDef.OnFixedUpdate += new hook_OnFixedUpdate(On_SkillDefFixedUpdate); } public override void Uninstall() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown base.Uninstall(); if (Module.instance.removeOriginals) { skillFamily1.ReplaceVariant(skillDef, origSkillDef); skillFamily2.ReplaceVariant(skillDef, origSkillDef); } else { skillFamily1.RemoveVariant(skillDef); skillFamily2.RemoveVariant(skillDef); } SkillDef.OnFixedUpdate -= new hook_OnFixedUpdate(On_SkillDefFixedUpdate); } private void On_SkillDefFixedUpdate(orig_OnFixedUpdate orig, SkillDef self, GenericSkill skillSlot, float deltaTime) { if (skillSlot.characterBody.HasBuff(stimmedBuff)) { skillSlot.RunRecharge(deltaTime * rechargeRate); } orig.Invoke(self, skillSlot, deltaTime); } } public class HealBeacon : Module { public class EntStateCallSupplyDropHealing : CallSupplyDropHealing { public override void OnEnter() { ((CallSupplyDropBase)this).supplyDropPrefab = Module.instance.beaconPrefab; ((CallSupplyDropBase)this).muzzleflashEffect = Module.instance.muzzleFlashPrefab; ((CallSupplyDropBase)this).OnEnter(); } } public class EntStateHealingMainState : HealZoneMainState { public override bool shouldShowEnergy => true; } private SkillFamily skillFamily1; private SkillFamily skillFamily2; private SkillDef origSkillDef; internal SkillDef skillDef; internal GameObject beaconPrefab; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Lifetime of the T.Beacon: Healing deployable.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillLifetime { get; private set; } = 20f; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Cooldown of T.Beacon: Healing.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillRecharge { get; private set; } = 40f; public override string enabledConfigDescription => "Contains config for the T.Beacon: Healing submodule of Modules.BeaconRebalance. Replaces Beacon: Healing."; public override bool managedEnable => false; public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); SerializableEntityStateType mainStateType = ContentAddition.AddEntityState(ref flag); skillFamily1 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop1SkillFamily"); skillFamily2 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop2SkillFamily"); origSkillDef = LegacyResourcesAPI.Load("skilldefs/captainbody/CallSupplyDropHealing"); skillDef = SkillUtil.CloneSkillDef(origSkillDef); skillDef.rechargeStock = 1; skillDef.baseRechargeInterval = skillRecharge; skillDef.skillName = "AdmiralSupplyDropHealing"; skillDef.skillNameToken = "ADMIRAL_SUPPLY_HEALING_NAME"; skillDef.skillDescriptionToken = "ADMIRAL_SUPPLY_HEALING_DESCRIPTION"; skillDef.activationState = activationState; LanguageAPI.Add(skillDef.skillNameToken, "T.Beacon: Healing"); LanguageAPI.Add(skillDef.skillDescriptionToken, "Temporary beacon. Heal all nearby allies for 10% of their maximum health every second."); ContentAddition.AddSkillDef(skillDef); GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load("prefabs/networkedobjects/captainsupplydrops/CaptainSupplyDrop, Healing"), "TempSetup, BeaconPrefabPrefab", false); ((Behaviour)val.GetComponent()).enabled = true; CaptainBeaconDecayer captainBeaconDecayer = val.AddComponent(); captainBeaconDecayer.lifetime = skillLifetime; val.GetComponent().mainStateType = mainStateType; beaconPrefab = PrefabAPI.InstantiateClone(val, "AdmiralSupplyDrop, Healing", true); Object.Destroy((Object)(object)val); } public override void Install() { base.Install(); if (Module.instance.removeOriginals) { skillFamily1.ReplaceVariant(origSkillDef, skillDef); skillFamily2.ReplaceVariant(origSkillDef, skillDef); } else { skillFamily1.AddVariant(skillDef); skillFamily2.AddVariant(skillDef); } } public override void Uninstall() { base.Uninstall(); if (Module.instance.removeOriginals) { skillFamily1.ReplaceVariant(skillDef, origSkillDef); skillFamily2.ReplaceVariant(skillDef, origSkillDef); } else { skillFamily1.RemoveVariant(skillDef); skillFamily2.RemoveVariant(skillDef); } } } public class EntStateCallJumpPad : BaseSkillState { public override void OnEnter() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ((BaseState)this).OnEnter(); if (((EntityState)this).isAuthority) { switch (((BaseSkillState)this).activatorSkillSlot.stock) { case 0: { CallAirstrike2 val2 = new CallAirstrike2(); ((AimThrowableBase)val2).projectilePrefab = Module.instance.jumpPadPrefabProj2; ((AimThrowableBase)val2).maxDistance = 100f; ((EntityState)this).outer.SetNextState((EntityState)(object)val2); break; } case 1: { CallAirstrike1 val = new CallAirstrike1(); ((AimThrowableBase)val).projectilePrefab = Module.instance.jumpPadPrefabProj1; ((AimThrowableBase)val).maxDistance = 100f; ((EntityState)this).outer.SetNextState((EntityState)(object)val); break; } default: AdmiralPlugin._logger.LogError((object)"Jump pad skill has invalid stock count!"); break; } } } 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)2; } } public class EntStateSetupJumpPad : SetupAirstrike { public override void OnEnter() { SkillDef primarySkillDef = SetupAirstrike.primarySkillDef; SetupAirstrike.primarySkillDef = Module.instance.callSkillDef; ((SetupAirstrike)this).OnEnter(); SetupAirstrike.primarySkillDef = primarySkillDef; } public override void OnExit() { SkillDef primarySkillDef = SetupAirstrike.primarySkillDef; SetupAirstrike.primarySkillDef = Module.instance.callSkillDef; ((SetupAirstrike)this).OnExit(); SetupAirstrike.primarySkillDef = primarySkillDef; } } public class OrbitalJumpPadSkill : Module { private struct MsgSetJumpPadTarget : INetMessage, ISerializableObject { private GameObject _targetJumpPad; private Vector3 _velocity; private Vector3 _targetPos; public void Serialize(NetworkWriter writer) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) writer.Write(_targetJumpPad); writer.Write(_velocity); writer.Write(_targetPos); } public void Deserialize(NetworkReader reader) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) _targetJumpPad = reader.ReadGameObject(); _velocity = reader.ReadVector3(); _targetPos = reader.ReadVector3(); } public void OnReceived() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_targetJumpPad)) { GameObject gameObject = ((Component)_targetJumpPad.transform.Find("mdlHumanFan").Find("JumpVolume")).gameObject; gameObject.GetComponent().jumpVelocity = _velocity; LineRenderer component = gameObject.GetComponent(); if (Module.instance.showArcs) { component.SetPositions(CalculateJumpPadPoints(gameObject.transform.position, _targetPos, 5f, 32)); } else { ((Renderer)component).enabled = false; } } } public MsgSetJumpPadTarget(GameObject targetJumpPad, Vector3 velocity, Vector3 targetPos) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) _targetJumpPad = targetJumpPad; _velocity = velocity; _targetPos = targetPos; } } internal SkillDef setupSkillDef; internal SkillDef callSkillDef; internal UnlockableDef unlockable; internal GameObject jumpPadPrefabBase; internal GameObject jumpPadPrefabProj1; internal GameObject jumpPadPrefabProj2; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Lifetime of the Orbital Jump Pad deployable.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillLifetime { get; private set; } = 20f; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Cooldown of Orbital Jump Pad.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillRecharge { get; private set; } = 50f; [AutoConfigRoOSlider("{0:N0} m", 0f, 300f, null, null)] [AutoConfig("Maximum range of both Orbital Jump Pad terminals.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float skillRange { get; private set; } = 80f; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If true, arcs previewing Orbital Jump Pad trajectory will appear.", AutoConfigFlags.None, new object[] { })] public bool showArcs { get; private set; } = true; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If true, Orbital Jump Pad will have a base stock of two and recharge two at once.", AutoConfigFlags.DeferForever, new object[] { })] public bool doubleStock { get; private set; } = true; public override string enabledConfigDescription => "Adds the Orbital Jump Pad utility skill variant."; public override AutoConfigFlags enabledConfigFlags => AutoConfigFlags.DeferForever; public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); SerializableEntityStateType activationState2 = ContentAddition.AddEntityState(ref flag); NetworkingAPI.RegisterMessageType(); string text = "ACHIEVEMENT_ADMIRAL_" + name.ToUpper(CultureInfo.InvariantCulture) + "_NAME"; string text2 = "ACHIEVEMENT_ADMIRAL_" + name.ToUpper(CultureInfo.InvariantCulture) + "_DESCRIPTION"; unlockable = ScriptableObject.CreateInstance(); unlockable.cachedName = "Admiral_" + name + "Unlockable"; unlockable.sortScore = 200; unlockable.achievementIcon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralJumpPadSkill.png"); ContentAddition.AddUnlockableDef(unlockable); LanguageAPI.Add(text, "Captain: Damn The Torpedoes"); LanguageAPI.Add(text2, "As Captain, nail a very speedy target with an Orbital Probe."); jumpPadPrefabBase = CommonCode.ModifyVanillaPrefab("RoR2/Base/frozenwall/FW_HumanFan.prefab", "CaptainJumpPad", shouldNetwork: true, ModifyJumpPadPrefab); jumpPadPrefabProj1 = CommonCode.ModifyVanillaPrefab("RoR2/Base/Captain/CaptainAirstrikeProjectile1.prefab", "CaptainJumpPadProjectile1", shouldNetwork: true, ModifyAirstrike1Prefab); ContentAddition.AddProjectile(jumpPadPrefabProj1); jumpPadPrefabProj2 = CommonCode.ModifyVanillaPrefab("RoR2/Base/Captain/CaptainAirstrikeProjectile1.prefab", "CaptainJumpPadProjectile2", shouldNetwork: true, ModifyAirstrike2Prefab); ContentAddition.AddProjectile(jumpPadPrefabProj2); string text3 = "ADMIRAL_JUMPPAD_SKILL_NAME"; string text4 = "ADMIRAL_JUMPPAD_SKILL_DESC"; string text5 = "Orbital Jump Pad"; LanguageAPI.Add(text3, text5); LanguageAPI.Add(text4, "Request an Orbital Jump Pad from the UES Safe Travels. Fire once to set the jump pad, then again to set its target (both within 80 m)."); setupSkillDef = ScriptableObject.CreateInstance(); setupSkillDef.activationStateMachineName = "Skillswap"; setupSkillDef.activationState = activationState2; setupSkillDef.interruptPriority = (InterruptPriority)1; setupSkillDef.baseRechargeInterval = skillRecharge; setupSkillDef.baseMaxStock = ((!doubleStock) ? 1 : 2); setupSkillDef.rechargeStock = ((!doubleStock) ? 1 : 2); setupSkillDef.beginSkillCooldownOnSkillEnd = true; setupSkillDef.requiredStock = 1; setupSkillDef.stockToConsume = 1; setupSkillDef.isCombatSkill = false; setupSkillDef.cancelSprintingOnActivation = true; setupSkillDef.canceledFromSprinting = true; setupSkillDef.mustKeyPress = true; setupSkillDef.fullRestockOnAssign = true; setupSkillDef.skillName = text5; setupSkillDef.skillNameToken = text3; setupSkillDef.skillDescriptionToken = text4; setupSkillDef.icon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralJumpPadSkill.png"); ContentAddition.AddSkillDef(setupSkillDef); callSkillDef = ScriptableObject.CreateInstance(); callSkillDef.activationStateMachineName = "Weapon"; callSkillDef.activationState = activationState; callSkillDef.interruptPriority = (InterruptPriority)2; callSkillDef.baseRechargeInterval = 0f; callSkillDef.baseMaxStock = 2; callSkillDef.rechargeStock = 0; callSkillDef.beginSkillCooldownOnSkillEnd = true; callSkillDef.requiredStock = 1; callSkillDef.stockToConsume = 1; callSkillDef.isCombatSkill = false; callSkillDef.cancelSprintingOnActivation = true; callSkillDef.canceledFromSprinting = true; callSkillDef.mustKeyPress = true; callSkillDef.fullRestockOnAssign = true; callSkillDef.dontAllowPastMaxStocks = true; callSkillDef.skillName = text5; callSkillDef.skillNameToken = text3; callSkillDef.skillDescriptionToken = text4; callSkillDef.icon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralJumpPadSkill.png"); ContentAddition.AddSkillDef(callSkillDef); } private void ProjectileExplosion_DetonateServer(orig_DetonateServer orig, ProjectileExplosion self) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (!NetworkServer.active) { return; } if (Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { GameObject owner = ((Component)self).GetComponent().owner; if (Object.op_Implicit((Object)(object)owner)) { OrbitalJumpPadDeployTracker orbitalJumpPadDeployTracker = owner.GetComponent(); if (!Object.op_Implicit((Object)(object)orbitalJumpPadDeployTracker)) { orbitalJumpPadDeployTracker = owner.AddComponent(); } GameObject val = Object.Instantiate(jumpPadPrefabBase, ((Component)self).transform.position, ((Component)self).transform.rotation); if (Object.op_Implicit((Object)(object)orbitalJumpPadDeployTracker.prevPadBase)) { Object.Destroy((Object)(object)orbitalJumpPadDeployTracker.prevPadBase); } orbitalJumpPadDeployTracker.prevPadBase = orbitalJumpPadDeployTracker.lastPadBase; orbitalJumpPadDeployTracker.lastPadBase = val; NetworkServer.Spawn(val); } } else { if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { return; } GameObject owner2 = ((Component)self).GetComponent().owner; if (!Object.op_Implicit((Object)(object)owner2)) { return; } OrbitalJumpPadDeployTracker component = owner2.GetComponent(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.lastPadBase)) { (Vector3, float) tuple = CalculateJumpPadTrajectory(component.lastPadBase.transform.position, ((Component)self).transform.position, 5f); if (!float.IsNaN(tuple.Item1.y)) { NetMessageExtensions.Send((INetMessage)(object)new MsgSetJumpPadTarget(component.lastPadBase, tuple.Item1, ((Component)self).transform.position), (NetworkDestination)1); component.lastPadBase.GetComponent().Open(); } else { Object.Destroy((Object)(object)component.lastPadBase); } } } } public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown base.Install(); JumpVolume.OnTriggerStay += new hook_OnTriggerStay(JumpVolume_OnTriggerStay); ProjectileExplosion.DetonateServer += new hook_DetonateServer(ProjectileExplosion_DetonateServer); SkillFamily targetFamily = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainUtilitySkillFamily"); targetFamily.AddVariant(setupSkillDef, unlockable); } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown base.Uninstall(); JumpVolume.OnTriggerStay -= new hook_OnTriggerStay(JumpVolume_OnTriggerStay); ProjectileExplosion.DetonateServer -= new hook_DetonateServer(ProjectileExplosion_DetonateServer); SkillFamily targetFamily = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainUtilitySkillFamily"); targetFamily.RemoveVariant(setupSkillDef); } public static (Vector3, float) CalculateJumpPadTrajectory(Vector3 source, Vector3 target, float extraPeakHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target - source; float y = val.y; float num = Mathf.Max(new float[3] { Mathf.Max(y, 0f) + extraPeakHeight, y, 0f }); float num2 = 0f - Physics.gravity.y; float num3 = Mathf.Sqrt(2f * num2 * num); float num4 = Mathf.Sqrt(2f) / num2 * (Mathf.Sqrt(num2 * (num - y)) + Mathf.Sqrt(num2 * num)); float num5 = val.x / num4; float num6 = val.z / num4; return (new Vector3(num5, num3, num6), num4); } public static Vector3[] CalculateJumpPadPoints(Vector3 source, Vector3 target, float extraPeakHeight, int displayPointsToGenerate) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target - source; float y = val.y; float num = Mathf.Max(new float[3] { Mathf.Max(y, 0f) + extraPeakHeight, y, 0f }); float num2 = 0f - Physics.gravity.y; float num3 = Mathf.Sqrt(2f * num2 * num); float num4 = Mathf.Sqrt(2f) / num2 * (Mathf.Sqrt(num2 * (num - y)) + Mathf.Sqrt(num2 * num)); float num5 = val.x / num4; float num6 = val.z / num4; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(num5, num3, num6); Vector3[] array = (Vector3[])(object)new Vector3[displayPointsToGenerate]; float num7 = num4 / ((float)displayPointsToGenerate - 1f); for (int i = 0; i < displayPointsToGenerate; i++) { array[i] = Trajectory.CalculatePositionAtTime(source, val2, num7 * (float)i); } return array; } private GameObject ModifyJumpPadPrefab(GameObject origPrefab) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown origPrefab.transform.localScale = new Vector3(0.75f, 0.125f, 0.75f); Transform val = origPrefab.transform.Find("mdlHumanFan").Find("JumpVolume"); Transform val2 = val.Find("LoopParticles").Find("Particle System"); val2.localScale = new Vector3(0.25f, 0.25f, 0.25f); MainModule main = ((Component)val2).gameObject.GetComponent().main; ((MainModule)(ref main)).startSpeed = new MinMaxCurve(6f); Transform val3 = val.Find("LoopParticles").Find("ForwardDust"); val3.localScale = new Vector3(0.25f, 0.25f, 0.25f); MainModule main2 = ((Component)val3).gameObject.GetComponent().main; ((MainModule)(ref main2)).startSpeed = new MinMaxCurve(0.5f, 12f); Transform val4 = val.Find("ActivateParticles").Find("ForwardDust"); val4.localScale = new Vector3(0.3f, 0.3f, 0.3f); MainModule main3 = ((Component)val4).gameObject.GetComponent().main; ((MainModule)(ref main3)).startSpeed = new MinMaxCurve(0.75f, 15f); Transform val5 = val.Find("ActivateParticles").Find("Circle"); val5.localScale = new Vector3(0.25f, 0.25f, 0.125f); LineRenderer val6 = ((Component)val).gameObject.AddComponent(); ((Renderer)val6).material = Object.Instantiate(LegacyResourcesAPI.Load("materials/matBlueprintsOk")); ((Renderer)val6).material.SetColor("_TintColor", new Color(2f, 0.2f, 10f, 3f)); val6.positionCount = 32; List list = new List(); for (int i = 0; i < val6.positionCount; i++) { list.Add(new Keyframe((float)i / 32f, (1f - CommonCode.Wrap((float)i / 8f, 0f, 1f)) * 0.875f)); } val6.widthCurve = new AnimationCurve { keys = list.ToArray() }; ((Behaviour)origPrefab.GetComponent()).enabled = false; ((Behaviour)origPrefab.GetComponent()).enabled = false; ((Behaviour)origPrefab.GetComponent()).enabled = false; ((Component)val).gameObject.AddComponent(); CaptainBeaconDecayer captainBeaconDecayer = origPrefab.AddComponent(); captainBeaconDecayer.lifetime = skillLifetime; return origPrefab; } private GameObject ModifyAirstrike1Prefab(GameObject origPrefab) { ProjectileImpactExplosion component = origPrefab.GetComponent(); ((ProjectileExplosion)component).blastDamageCoefficient = 0.1f; ((ProjectileExplosion)component).blastRadius = 5f; component.lifetime = 0.5f; origPrefab.AddComponent(); return origPrefab; } private GameObject ModifyAirstrike2Prefab(GameObject origPrefab) { ProjectileImpactExplosion component = origPrefab.GetComponent(); ((ProjectileExplosion)component).blastDamageCoefficient = 0.05f; ((ProjectileExplosion)component).blastRadius = 2.5f; component.lifetime = 0.5f; origPrefab.AddComponent(); return origPrefab; } private void JumpVolume_OnTriggerStay(orig_OnTriggerStay orig, JumpVolume self, Collider other) { orig.Invoke(self, other); TemporaryFallProtectionProvider component = ((Component)self).GetComponent(); CharacterBody component2 = ((Component)other).GetComponent(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.characterMotor)) { TemporaryFallDamageProtection temporaryFallDamageProtection = ((Component)other).GetComponent(); if (!Object.op_Implicit((Object)(object)temporaryFallDamageProtection)) { temporaryFallDamageProtection = ((Component)other).gameObject.AddComponent(); } temporaryFallDamageProtection.Apply(); } } } public class TemporaryFallDamageProtection : NetworkBehaviour { private CharacterBody attachedBody; private bool hasProtection = false; private bool disableNextFrame = false; private bool disableN2f = false; private void FixedUpdate() { //IL_0040: 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_0048: Unknown result type (might be due to invalid IL or missing references) if (disableN2f) { disableN2f = false; disableNextFrame = true; } else if (disableNextFrame) { disableNextFrame = false; hasProtection = false; CharacterBody obj = attachedBody; obj.bodyFlags = (BodyFlags)(obj.bodyFlags & -2); } else if (hasProtection && ((BaseCharacterController)attachedBody.characterMotor).Motor.GroundingStatus.IsStableOnGround && !((BaseCharacterController)attachedBody.characterMotor).Motor.LastGroundingStatus.IsStableOnGround) { disableN2f = true; } } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown attachedBody = ((Component)this).GetComponent(); attachedBody.characterMotor.onMovementHit += new MovementHitDelegate(CharacterMotor_onMovementHit); } public void Apply() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) hasProtection = true; CharacterBody obj = attachedBody; obj.bodyFlags = (BodyFlags)(obj.bodyFlags | 1); } private void CharacterMotor_onMovementHit(ref MovementHitInfo movementHitInfo) { if (hasProtection && !disableN2f && !disableNextFrame) { disableN2f = true; } } } public class TemporaryFallProtectionProvider : MonoBehaviour { } public class OrbitalJumpPadDeployTracker : MonoBehaviour { public GameObject lastPadBase; public GameObject prevPadBase; } public class OrbitalJumpPad1ImpactEventFlag : MonoBehaviour { } public class OrbitalJumpPad2ImpactEventFlag : MonoBehaviour { } [RegisterAchievement("Admiral_OrbitalJumpPadSkill", "Admiral_OrbitalJumpPadSkillUnlockable", "CompleteMainEnding", 5u, null)] public class AdmiralJumpPadAchievement : BaseAchievement { private int projTestInd1 = -1; private int projTestInd2 = -1; private int projTestInd3 = -1; public override bool wantsBodyCallbacks => true; public override BodyIndex LookUpRequiredBodyIndex() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("CaptainBody"); } public override void OnInstall() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown ((BaseAchievement)this).OnInstall(); GlobalEventManager.onServerDamageDealt += GlobalEventManager_onServerDamageDealt; CharacterBody.Awake += new hook_Awake(CharacterBody_Awake); projTestInd1 = ProjectileCatalog.FindProjectileIndex("CaptainAirstrikeProjectile1"); projTestInd2 = ProjectileCatalog.FindProjectileIndex("CaptainAirstrikeProjectile2"); projTestInd3 = ProjectileCatalog.FindProjectileIndex("CaptainAirstrikeProjectile3"); } public override void OnUninstall() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown ((BaseAchievement)this).OnUninstall(); GlobalEventManager.onServerDamageDealt -= GlobalEventManager_onServerDamageDealt; CharacterBody.Awake -= new hook_Awake(CharacterBody_Awake); } private void CharacterBody_Awake(orig_Awake orig, CharacterBody self) { orig.Invoke(self); ((Component)self).gameObject.AddComponent(); } private void GlobalEventManager_onServerDamageDealt(DamageReport obj) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) if (!((BaseAchievement)this).meetsBodyRequirement || !Object.op_Implicit((Object)(object)obj.victimBody) || !Object.op_Implicit((Object)(object)obj.damageInfo.attacker) || !Object.op_Implicit((Object)(object)obj.damageInfo.inflictor) || NetworkUser.readOnlyLocalPlayersList.Count == 0) { return; } GameObject attacker = obj.damageInfo.attacker; CharacterBody currentBody = NetworkUser.readOnlyLocalPlayersList[0].GetCurrentBody(); if ((Object)(object)attacker != (Object)(object)((currentBody != null) ? ((Component)currentBody).gameObject : null)) { return; } int projectileIndex = ProjectileCatalog.GetProjectileIndex(obj.damageInfo.inflictor); if (projectileIndex != projTestInd1 && projectileIndex != projTestInd2 && projectileIndex != projTestInd3) { return; } AverageSpeedTracker component = ((Component)obj.victimBody).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { float num = component.QuerySpeed(); Vector3 val = obj.damageInfo.position - obj.damageInfo.inflictor.transform.position; float magnitude = ((Vector3)(ref val)).magnitude; if (num > 20f && magnitude < 4f) { ((BaseAchievement)this).Grant(); } } } } public class AverageSpeedTracker : MonoBehaviour { private readonly List positions = new List(); private readonly List deltas = new List(); public float pollingRate = 0.2f; private uint _history = 5u; private float stopwatch = 0f; public uint history { get { return _history; } set { positions.Clear(); deltas.Clear(); _history = value; } } private void FixedUpdate() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) stopwatch += Time.fixedDeltaTime; if (stopwatch > pollingRate) { positions.Add(((Component)this).transform.position); deltas.Add(stopwatch); if (positions.Count >= _history) { positions.RemoveAt(0); deltas.RemoveAt(0); } stopwatch = 0f; } } public float QuerySpeed() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) float num = 0f; for (int i = 0; i < positions.Count - 1; i++) { float num2 = num; Vector3 val = positions[i + 1] - positions[i]; num = num2 + ((Vector3)(ref val)).magnitude / deltas[i + 1]; } return num; } } public class OrbitalSkillsAnywhere : Module { private Hook CUOSHook; public override string enabledConfigDescription => "Allows orbital skills to be used anywhere except Bazaar."; public override void SetupBehavior() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown base.SetupBehavior(); MethodInfo methodCached = Reflection.GetMethodCached(typeof(CaptainOrbitalSkillDef), "get_isAvailable"); MethodInfo methodCached2 = Reflection.GetMethodCached(typeof(OrbitalSkillsAnywhere), "Hook_Get_IsAvailable"); CUOSHook = new Hook((MethodBase)methodCached, methodCached2, new HookConfig { ManualApply = true }); } public override void Install() { base.Install(); CUOSHook.Apply(); } public override void Uninstall() { base.Uninstall(); CUOSHook.Undo(); } private static bool Hook_Get_IsAvailable(CaptainOrbitalSkillDef self) { return SceneCatalog.mostRecentSceneDef.baseSceneName != "bazaar"; } } public class ShockBeacon : Module { public class EntStateCallSupplyDropShocking : CallSupplyDropShocking { public override void OnEnter() { ((CallSupplyDropBase)this).supplyDropPrefab = Module.instance.beaconPrefab; ((CallSupplyDropBase)this).muzzleflashEffect = Module.instance.muzzleFlashPrefab; ((CallSupplyDropBase)this).OnEnter(); } } public class EntStateShockingMainState : ShockZoneMainState { public override bool shouldShowEnergy => true; public override void FixedUpdate() { ((EntityState)this).fixedAge = ((EntityState)this).fixedAge + Time.fixedDeltaTime; base.shockTimer += Time.fixedDeltaTime; if (base.shockTimer > Module.instance.shockRate) { base.shockTimer -= Module.instance.shockRate; ((ShockZoneMainState)this).Shock(); } } } private SkillFamily skillFamily1; private SkillFamily skillFamily2; private SkillDef origSkillDef; internal SkillDef skillDef; internal GameObject beaconPrefab; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Lifetime of the T.Beacon: Shocking deployable.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillLifetime { get; private set; } = 8f; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Cooldown of T.Beacon: Shocking.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillRecharge { get; private set; } = 24f; [AutoConfigRoOSlider("{0:N2} s", 0f, 30f, null, null)] [AutoConfig("Fire rate of T.Beacon: Shocking.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float shockRate { get; private set; } = 0.95f; public override string enabledConfigDescription => "Contains config for the T.Beacon: Shocking submodule of Modules.BeaconRebalance. Replaces Beacon: Shocking."; public override bool managedEnable => false; public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); SerializableEntityStateType mainStateType = ContentAddition.AddEntityState(ref flag); skillFamily1 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop1SkillFamily"); skillFamily2 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop2SkillFamily"); origSkillDef = LegacyResourcesAPI.Load("skilldefs/captainbody/CallSupplyDropShocking"); skillDef = SkillUtil.CloneSkillDef(origSkillDef); skillDef.rechargeStock = 1; skillDef.baseRechargeInterval = skillRecharge; skillDef.skillName = "AdmiralSupplyDropShocking"; skillDef.skillNameToken = "ADMIRAL_SUPPLY_SHOCKING_NAME"; skillDef.skillDescriptionToken = "ADMIRAL_SUPPLY_SHOCKING_DESCRIPTION"; skillDef.activationState = activationState; LanguageAPI.Add(skillDef.skillNameToken, "T.Beacon: Shocking"); LanguageAPI.Add(skillDef.skillDescriptionToken, "Temporary beacon. Shock all nearby enemies rapidly for a short time."); ContentAddition.AddSkillDef(skillDef); GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load("prefabs/networkedobjects/captainsupplydrops/CaptainSupplyDrop, Shocking"), "TempSetup, BeaconPrefabPrefab", false); ((Behaviour)val.GetComponent()).enabled = true; CaptainBeaconDecayer captainBeaconDecayer = val.AddComponent(); captainBeaconDecayer.lifetime = skillLifetime; val.GetComponent().mainStateType = mainStateType; beaconPrefab = PrefabAPI.InstantiateClone(val, "AdmiralSupplyDrop, Shocking", true); Object.Destroy((Object)(object)val); } public override void Install() { base.Install(); if (Module.instance.removeOriginals) { skillFamily1.ReplaceVariant(origSkillDef, skillDef); skillFamily2.ReplaceVariant(origSkillDef, skillDef); } else { skillFamily1.AddVariant(skillDef); skillFamily2.AddVariant(skillDef); } } public override void Uninstall() { base.Uninstall(); if (Module.instance.removeOriginals) { skillFamily1.ReplaceVariant(skillDef, origSkillDef); skillFamily2.ReplaceVariant(skillDef, origSkillDef); } else { skillFamily1.RemoveVariant(skillDef); skillFamily2.RemoveVariant(skillDef); } } } internal class ShockedOrb : LightningOrb { public GameObject shockVictim; } public class ShockStatusTweaks : Module { [AutoConfigRoOSlider("{0:P2}", 0f, 1f, null, null)] [AutoConfig("Chance per frame to shock a nearby ally.", AutoConfigFlags.None, new object[] { 0f, 1f })] public float shockChance { get; private set; } = 0.033f; [AutoConfigRoOSlider("{0:P1}", 0f, 2f, null, null)] [AutoConfig("Percentage of attacker max health dealt in damage per shock orb.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float shockDamageFrac { get; private set; } = 0.02f; [AutoConfigRoOSlider("{0:N0} m", 0f, 100f, null, null)] [AutoConfig("Range within which Shocked can damage allies.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float shockRadius { get; private set; } = 15f; [AutoConfigRoOSlider("{0:P0}", 0f, 1f, null, null)] [AutoConfig("Proc coefficient of Shocked arcs.", AutoConfigFlags.None, new object[] { 0f, 1f })] public float shockProcCoef { get; private set; } = 0.1f; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If true, the damage threshold for breaking an enemy out of Shocked will be increased to ridiculous levels.", AutoConfigFlags.None, new object[] { })] public bool doThresholdTweak { get; private set; } = true; public override string enabledConfigDescription => "Removes the health threshold from the Shocked status and causes it to deal AoE damage based on victim max health."; public override AutoConfigUpdateActionTypes enabledConfigUpdateActionTypes => AutoConfigUpdateActionTypes.InvalidateLanguage; public override void InstallLanguage() { base.InstallLanguage(); languageOverlays.Add(LanguageAPI.AddOverlay("KEYWORD_SHOCKING", "ShockingInterrupts enemies and temporarily stuns them. A victim of Shocking will damage their nearby allies for a fraction of their own maximum health per second.")); } public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown base.Install(); ShockState.OnEnter += new hook_OnEnter(On_ShockStateOnEnter); ShockState.FixedUpdate += new hook_FixedUpdate(On_ShockStateFixedUpdate); SetStateOnHurt.OnTakeDamageServer += new Manipulator(IL_SSOHTakeDamageServer); } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown base.Uninstall(); ShockState.OnEnter -= new hook_OnEnter(On_ShockStateOnEnter); ShockState.FixedUpdate -= new hook_FixedUpdate(On_ShockStateFixedUpdate); SetStateOnHurt.OnTakeDamageServer -= new Manipulator(IL_SSOHTakeDamageServer); } private void IL_SSOHTakeDamageServer(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "SetShock") }); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate>((Action)delegate(SetStateOnHurt ssoh, DamageReport dr) { ShockHelper shockHelper = ((Component)ssoh.targetStateMachine).gameObject.GetComponent(); if (!Object.op_Implicit((Object)(object)shockHelper)) { shockHelper = ((Component)ssoh.targetStateMachine).gameObject.AddComponent(); } shockHelper.currentAttacker = dr.attacker; }); } private void On_ShockStateOnEnter(orig_OnEnter orig, ShockState self) { orig.Invoke(self); if (doThresholdTweak) { self.healthFractionToForceExit = 100f; } } private void On_ShockStateFixedUpdate(orig_FixedUpdate orig, ShockState self) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (!NetworkServer.active || !(base.rng.nextNormalizedFloat < shockChance)) { return; } TeamComponent teamComponent = ((EntityState)self).outer.commonComponents.teamComponent; List list = new List(); bool flag = (int)FriendlyFireManager.friendlyFireMode > 0; if (flag || (int)teamComponent.teamIndex == 2) { list.AddRange(TeamComponent.GetTeamMembers((TeamIndex)2)); } if (flag || (int)teamComponent.teamIndex == 0) { list.AddRange(TeamComponent.GetTeamMembers((TeamIndex)0)); } if (flag || (int)teamComponent.teamIndex == 1) { list.AddRange(TeamComponent.GetTeamMembers((TeamIndex)1)); } float sqrad = shockRadius * shockRadius; Vector3 tpos = ((EntityState)self).outer.commonComponents.characterBody.transform.position; list.Remove(teamComponent); list.RemoveAll(delegate(TeamComponent x) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = ((Component)x).transform.position - tpos; return ((Vector3)(ref val2)).sqrMagnitude > sqrad || !Object.op_Implicit((Object)(object)x.body) || !Object.op_Implicit((Object)(object)x.body.mainHurtBox) || !((Behaviour)x.body).isActiveAndEnabled; }); if (list.Count != 0) { TeamComponent val = base.rng.NextElementUniform(list); GameObject attacker = null; ShockHelper component = ((EntityState)self).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { attacker = component.currentAttacker; } OrbManager.instance.AddOrb((Orb)(object)new ShockedOrb { attacker = attacker, bouncesRemaining = 0, damageColorIndex = (DamageColorIndex)0, damageType = DamageTypeCombo.op_Implicit((DamageType)131072), damageValue = ((EntityState)self).outer.commonComponents.characterBody.maxHealth * shockDamageFrac, isCrit = false, lightningType = (LightningType)1, origin = tpos, procChainMask = default(ProcChainMask), procCoefficient = shockProcCoef, target = val.body.mainHurtBox, teamIndex = (TeamIndex)(-1), shockVictim = ((EntityState)self).gameObject }); } } } public class ShockHelper : MonoBehaviour { public GameObject currentAttacker; public int shockKills = 0; } public class ShotgunAutofire : Module { [AutoConfigRoOSlider("{0:N2} s", 0f, 10f, null, null)] [AutoConfig("Time, in fraction of total charge time, to wait before autofiring Vulcan Shotgun after reaching full charge.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float fireDelayDynamic { get; private set; } = 0.2f; [AutoConfigRoOSlider("{0:N2} s", 0f, 10f, null, null)] [AutoConfig("Absolute minimum time, in seconds, to wait before autofiring Vulcan Shotgun after reaching full charge.", AutoConfigFlags.None, new object[] { 0f, float.MaxValue })] public float fireDelayFixed { get; private set; } = 0f; public override bool managedEnable => true; public override string enabledConfigDescription => "Causes Vulcan Shotgun to autofire. Client-side."; public override AutoConfigFlags enabledConfigFlags => AutoConfigFlags.None; public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.Install(); ChargeCaptainShotgun.FixedUpdate += new hook_FixedUpdate(On_CapChargeShotgunFixedUpdate); } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.Uninstall(); ChargeCaptainShotgun.FixedUpdate -= new hook_FixedUpdate(On_CapChargeShotgunFixedUpdate); } private void On_CapChargeShotgunFixedUpdate(orig_FixedUpdate orig, ChargeCaptainShotgun self) { if (Util.HasEffectiveAuthority(((EntityState)self).outer.networkIdentity) && ((EntityState)self).fixedAge / self.chargeDuration > fireDelayDynamic + 1f && ((EntityState)self).fixedAge - self.chargeDuration > fireDelayFixed) { self.released = true; } orig.Invoke(self); } } public class ShotgunRebalance : Module { [AutoConfigRoOIntSlider("{0:N0}", 1, 30, null, null)] [AutoConfig("Pellet count for Vulcan Shotgun.", AutoConfigFlags.None, new object[] { 1, int.MaxValue })] public int pelletCount { get; private set; } = 6; public override bool managedEnable => true; public override string enabledConfigDescription => "Reduces Vulcan Shotgun pellet count."; public override AutoConfigUpdateActionTypes enabledConfigUpdateActionTypes => AutoConfigUpdateActionTypes.InvalidateLanguage; public override void InstallLanguage() { genericLanguageTokens["CAPTAIN_PRIMARY_DESCRIPTION"] = "Fire a blast of pellets that deal 6x120% damage with no falloff. Charging the attack narrows the spread."; base.InstallLanguage(); } public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown base.Install(); FireCaptainShotgun.ModifyBullet += new hook_ModifyBullet(On_FCSModifyBullet); FireCaptainShotgun.ctor += new hook_ctor(On_FireCaptainShotgunCtor); } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown base.Uninstall(); FireCaptainShotgun.ModifyBullet -= new hook_ModifyBullet(On_FCSModifyBullet); FireCaptainShotgun.ctor -= new hook_ctor(On_FireCaptainShotgunCtor); } private void On_FCSModifyBullet(orig_ModifyBullet orig, FireCaptainShotgun self, BulletAttack bulletAttack) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, bulletAttack); bulletAttack.falloffModel = (FalloffModel)0; } private void On_FireCaptainShotgunCtor(orig_ctor orig, FireCaptainShotgun self) { orig.Invoke(self); ((GenericBulletBaseState)self).bulletCount = pelletCount; } } public class EntStateChargeSKGun : ChargeCaptainShotgun { public override void OnEnter() { ((ChargeCaptainShotgun)this).OnEnter(); base.chargeDuration = Mathf.Max(base.chargeDuration, Module.instance.minChargeTime); } public override void FixedUpdate() { ((EntityState)this).fixedAge = ((EntityState)this).fixedAge + Time.fixedDeltaTime; ((EntityState)this).characterBody.SetAimTimer(1f); ((EntityState)this).characterBody.isSprinting = false; if (((EntityState)this).fixedAge >= base.chargeDuration) { if (Object.op_Implicit((Object)(object)base.chargeupVfxGameObject)) { EntityState.Destroy((Object)(object)base.chargeupVfxGameObject); base.chargeupVfxGameObject = null; } if (!Object.op_Implicit((Object)(object)base.holdChargeVfxGameObject) && Object.op_Implicit((Object)(object)base.muzzleTransform)) { base.holdChargeVfxGameObject = Object.Instantiate(ChargeCaptainShotgun.holdChargeVfxPrefab, base.muzzleTransform); } } if (((EntityState)this).isAuthority) { if (!base.released && !(((EntityState)this).inputBank?.skill1.down ?? false)) { base.released = true; } if (base.released) { ((EntityState)this).outer.SetNextState((EntityState)(object)new EntStateFireSKGun()); } } } } public class EntStateFireSKGun : BaseState { private float duration; private float firingDelay; private bool isCharged; private bool usedAllAmmo; private bool hasFired = false; public override void OnEnter() { //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) isCharged = ((EntityState)this).characterBody.spreadBloomAngle <= 2f; ((BaseState)this).OnEnter(); if (isCharged || ((EntityState)this).skillLocator.primary.stock == 0) { usedAllAmmo = true; ((EntityState)this).skillLocator.primary.stock = 0; ((EntityState)this).skillLocator.primary.rechargeStopwatch = 0.5f - 1.25f / base.attackSpeedStat; duration = 1.25f / base.attackSpeedStat; firingDelay = (isCharged ? 0.35f : 0.2f) / base.attackSpeedStat; ((EntityState)this).outer.commonComponents.characterBody.AddTimedBuff(Module.instance.slowSkillDebuff, duration); } else { ((EntityState)this).skillLocator.primary.rechargeStopwatch = 0.5f * (1f - 1f / base.attackSpeedStat); duration = 0.5f / base.attackSpeedStat; firingDelay = 0f; } firingDelay = Mathf.Min(firingDelay, duration); Ray aimRay = ((BaseState)this).GetAimRay(); ((BaseState)this).StartAimMode(aimRay, duration + 2f, false); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= firingDelay && !hasFired) { Fire(); hasFired = true; } if (((EntityState)this).fixedAge >= duration) { ((EntityState)this).PlayAnimation("Gesture, Override", "BufferEmpty"); ((EntityState)this).outer.SetNextStateToMain(); } } private void Fire() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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) FireCaptainShotgun val = new FireCaptainShotgun(); ((EntityState)this).PlayAnimation("Gesture, Additive", "FireCaptainShotgun"); ((EntityState)this).PlayAnimation("Gesture, Override", "FireCaptainShotgun"); Util.PlaySound(isCharged ? FireCaptainShotgun.tightSoundString : FireCaptainShotgun.wideSoundString, ((EntityState)this).gameObject); if (Object.op_Implicit((Object)(object)((BaseState)this).FindModelChild(((GenericBulletBaseState)val).muzzleName))) { EffectManager.SimpleMuzzleFlash(((GenericBulletBaseState)val).muzzleFlashPrefab, ((EntityState)this).gameObject, ((GenericBulletBaseState)val).muzzleName, false); } Ray aimRay = ((BaseState)this).GetAimRay(); if (usedAllAmmo && Object.op_Implicit((Object)(object)((EntityState)this).outer.commonComponents.characterMotor)) { ((EntityState)this).outer.commonComponents.characterMotor.ApplyForce(((EntityState)this).outer.commonComponents.characterMotor.mass * (isCharged ? (-35f) : (-20f)) * ((Ray)(ref aimRay)).direction, true, false); } if (((EntityState)this).isAuthority) { ProjectileManager.instance.FireProjectile(isCharged ? Module.instance.chargedProjectilePrefab : Module.instance.projectilePrefab, ((Ray)(ref aimRay)).origin, Util.QuaternionSafeLookRotation(((Ray)(ref aimRay)).direction), ((EntityState)this).gameObject, base.damageStat * (isCharged ? 18f : (usedAllAmmo ? 8f : 5f)), isCharged ? 2f : 10f, Util.CheckRoll(base.critStat, ((EntityState)this).characterBody.master), (DamageColorIndex)0, (GameObject)null, -1f, (DamageTypeCombo?)null); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)((!usedAllAmmo) ? 1 : 2); } } public class SKGunSkill : Module { public const float recoveryTime = 0.5f; public const float fullReloadTime = 1.25f; internal BuffDef slowSkillDebuff; internal UnlockableDef unlockable; internal SkillDef skillDef; internal StatDef shotgunKillsStatDef; internal GameObject projectilePrefab; internal GameObject chargedProjectilePrefab; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If false, Valiant Blaster reload rate will not increase with attack speed.", AutoConfigFlags.None, new object[] { })] public bool attackSpeedAffectsReload { get; private set; } = true; [AutoConfigRoOSlider("{0:N2} s", 0f, 5f, null, null)] [AutoConfig("Minimum time required to fully charge Valiant Blaster (does not affect base charge time, only attack speed scaling).", AutoConfigFlags.None, new object[] { })] public float minChargeTime { get; private set; } = 0.5f; public override string enabledConfigDescription => "Adds the Valiant Blaster primary skill variant."; public override AutoConfigFlags enabledConfigFlags => AutoConfigFlags.DeferForever; public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); SerializableEntityStateType val = ContentAddition.AddEntityState(ref flag); string text = "ADMIRAL_SKGUN_SKILL_NAME"; string text2 = "ADMIRAL_SKGUN_SKILL_DESC"; string text3 = "Valiant Blaster"; LanguageAPI.Add(text, text3); LanguageAPI.Add(text2, "Fire a rapid combo of up to 3 slow-moving explosive orbs for 1x500%, 1x500%, and 1x800% damage. Fully charge to fire a faster, heavier round for 1x1800% damage. Must stand still to reload after firing a 3rd or charged shot -- cancel the combo to stay mobile."); chargedProjectilePrefab = CommonCode.ModifyVanillaPrefab("RoR2/Base/Vagrant/VagrantCannon.prefab", "CaptainSkGunChargedProjectile", shouldNetwork: true, delegate(GameObject projPfbPfb) { //IL_0074: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) projPfbPfb.GetComponent().desiredForwardSpeed = 150f; projPfbPfb.GetComponent().lifetime = 3f; projPfbPfb.GetComponent().enableVelocityOverLifetime = false; projPfbPfb.GetComponent().radius = 0.5f; ((ProjectileExplosion)projPfbPfb.GetComponent()).blastRadius = 12f; ((ProjectileExplosion)projPfbPfb.GetComponent()).blastDamageCoefficient = 1f; projPfbPfb.GetComponent().lifetime = 3f; ((ProjectileExplosion)projPfbPfb.GetComponent()).bonusBlastForce = Vector3.zero; GameObject val5 = PrefabAPI.InstantiateClone(projPfbPfb.GetComponent().impactEffect, "CaptainSkGunChargedImpactEffect", false); foreach (Transform item in val5.transform) { Transform val6 = item; val6.localScale *= 1.5f; } ContentAddition.AddEffect(val5); projPfbPfb.GetComponent().impactEffect = val5; return projPfbPfb; }); ContentAddition.AddProjectile(chargedProjectilePrefab); projectilePrefab = CommonCode.ModifyVanillaPrefab("RoR2/Base/Vagrant/VagrantCannon.prefab", "CaptainSkGunProjectile", shouldNetwork: true, delegate(GameObject projPfbPfb) { //IL_0074: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) projPfbPfb.GetComponent().desiredForwardSpeed = 35f; projPfbPfb.GetComponent().lifetime = 3f; projPfbPfb.GetComponent().enableVelocityOverLifetime = false; projPfbPfb.GetComponent().radius = 0.25f; ((ProjectileExplosion)projPfbPfb.GetComponent()).blastRadius = 5f; ((ProjectileExplosion)projPfbPfb.GetComponent()).blastDamageCoefficient = 1f; projPfbPfb.GetComponent().lifetime = 3f; ((ProjectileExplosion)projPfbPfb.GetComponent()).bonusBlastForce = Vector3.zero; GameObject val2 = PrefabAPI.InstantiateClone(projPfbPfb.GetComponent().impactEffect, "CaptainSkGunImpactEffect", false); foreach (Transform item2 in val2.transform) { Transform val3 = item2; val3.localScale *= 0.625f; } ContentAddition.AddEffect(val2); projPfbPfb.GetComponent().impactEffect = val2; GameObject val4 = PrefabAPI.InstantiateClone(projPfbPfb.GetComponent().ghostPrefab, "CaptainSkGunProjectileGhost", false); Object.Destroy((Object)(object)((Component)val4.transform.Find("Mesh")).GetComponent()); val4.transform.Find("Mesh").localScale = Vector3.one * 2f; val4.transform.Find("Spit, World").localScale = Vector3.one * 0.5f; projPfbPfb.GetComponent().ghostPrefab = val4; return projPfbPfb; }); ContentAddition.AddProjectile(projectilePrefab); skillDef = ScriptableObject.CreateInstance(); skillDef.activationStateMachineName = "Weapon"; skillDef.activationState = activationState; skillDef.interruptPriority = (InterruptPriority)1; skillDef.baseRechargeInterval = 0.5f; skillDef.baseMaxStock = 3; skillDef.rechargeStock = 3; skillDef.beginSkillCooldownOnSkillEnd = true; skillDef.requiredStock = 1; skillDef.stockToConsume = 1; skillDef.isCombatSkill = true; skillDef.cancelSprintingOnActivation = true; skillDef.canceledFromSprinting = false; skillDef.mustKeyPress = true; skillDef.fullRestockOnAssign = true; skillDef.dontAllowPastMaxStocks = true; skillDef.skillName = text3; skillDef.skillNameToken = text; skillDef.skillDescriptionToken = text2; skillDef.icon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralSKGunSkill.png"); ContentAddition.AddSkillDef(skillDef); string text4 = "ACHIEVEMENT_ADMIRAL_" + name.ToUpper(CultureInfo.InvariantCulture) + "_NAME"; string text5 = "ACHIEVEMENT_ADMIRAL_" + name.ToUpper(CultureInfo.InvariantCulture) + "_DESCRIPTION"; unlockable = ScriptableObject.CreateInstance(); unlockable.cachedName = "Admiral_" + name + "Unlockable"; unlockable.sortScore = 200; unlockable.achievementIcon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralSKGunSkill.png"); ContentAddition.AddUnlockableDef(unlockable); LanguageAPI.Add(text4, "Captain: Well-Seasoned"); LanguageAPI.Add(text5, "As Captain, hit with Vulcan Shotgun 600 TOTAL times."); shotgunKillsStatDef = StatDef.Register("admiralSKGunAchievementProgress", (StatRecordType)0, (StatDataType)0, 0.0, (DisplayValueFormatterDelegate)null); slowSkillDebuff = ScriptableObject.CreateInstance(); slowSkillDebuff.buffColor = Color.yellow; slowSkillDebuff.canStack = false; slowSkillDebuff.iconSprite = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralHeavyWeaponDebuff.png"); slowSkillDebuff.isDebuff = true; ((Object)slowSkillDebuff).name = "AdmiralHeavyWeaponDebuff"; ContentAddition.AddBuffDef(slowSkillDebuff); } public override void Install() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown base.Install(); LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainPrimarySkillFamily").AddVariant(skillDef, unlockable); CharacterBody.RecalculateStats += new hook_RecalculateStats(CharacterBody_RecalculateStats); } public override void Uninstall() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown base.Uninstall(); LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainPrimarySkillFamily").RemoveVariant(skillDef); CharacterBody.RecalculateStats -= new hook_RecalculateStats(CharacterBody_RecalculateStats); } private void CharacterBody_RecalculateStats(orig_RecalculateStats orig, CharacterBody self) { orig.Invoke(self); if (self.HasBuff(slowSkillDebuff)) { self.moveSpeed = 0f; self.acceleration = 80f; self.jumpPower = 0f; self.maxJumpHeight = 0f; } } } [RegisterAchievement("Admiral_SKGunSkill", "Admiral_SKGunSkillUnlockable", "CompleteMainEnding", 1u, null)] public class AdmiralSKGunAchievement : BaseAchievement { public override bool wantsBodyCallbacks => true; public override BodyIndex LookUpRequiredBodyIndex() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return BodyCatalog.FindBodyIndex("CaptainBody"); } public override float ProgressForAchievement() { return (float)((BaseAchievement)this).userProfile.statSheet.GetStatValueULong(Module.instance.shotgunKillsStatDef) / 600f; } public override void OnInstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown ((BaseAchievement)this).OnInstall(); BulletAttack.ProcessHitList += new hook_ProcessHitList(BulletAttack_ProcessHitList); } public override void OnUninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown ((BaseAchievement)this).OnUninstall(); BulletAttack.ProcessHitList -= new hook_ProcessHitList(BulletAttack_ProcessHitList); } private GameObject BulletAttack_ProcessHitList(orig_ProcessHitList orig, BulletAttack self, List hits, ref Vector3 endPosition, List ignoreList) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) GameObject val = orig.Invoke(self, hits, ref endPosition, ignoreList); if ((Object)(object)val == (Object)null) { return val; } CharacterBody val2 = (Object.op_Implicit((Object)(object)self.owner) ? self.owner.GetComponent() : null); if (!Object.op_Implicit((Object)(object)val2) || val2.bodyIndex != ((BaseAchievement)this).LookUpRequiredBodyIndex()) { return val; } HealthComponent component = val.GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return val; } TeamComponent component2 = val.GetComponent(); if (!Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)val2.teamComponent) || component2.teamIndex == val2.teamComponent.teamIndex) { return val; } Debug.Log((object)$"hit! {((BaseAchievement)this).userProfile.statSheet.GetStatValueULong(Module.instance.shotgunKillsStatDef)}"); ((BaseAchievement)this).userProfile.statSheet.PushStatValue(Module.instance.shotgunKillsStatDef, 1uL); if (((BaseAchievement)this).ProgressForAchievement() >= 1f) { ((BaseAchievement)this).Grant(); } return val; } } public class StasisBeacon : Module { public class EntStateCallSupplyDropStasis : CallSupplyDropEquipmentRestock { public override void OnEnter() { ((CallSupplyDropBase)this).supplyDropPrefab = Module.instance.beaconPrefab; ((CallSupplyDropBase)this).muzzleflashEffect = Module.instance.muzzleFlashPrefab; ((CallSupplyDropBase)this).OnEnter(); } } public class EntStateStasisMainState : EquipmentRestockMainState { public override bool shouldShowEnergy => true; public override void OnEnter() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) ((BaseCaptainSupplyDropState)this).OnEnter(); if (NetworkServer.active) { GameObject val = Object.Instantiate(Module.instance.stasisWardPrefab, ((EntityState)this).outer.commonComponents.transform.position, ((EntityState)this).outer.commonComponents.transform.rotation); val.GetComponent().teamIndex = ((BaseCaptainSupplyDropState)this).teamFilter.teamIndex; NetworkServer.Spawn(val); } } public override Interactability GetInteractability(Interactor activator) { //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 (Interactability)0; } } private const float _STASIS_INTERVAL = 2f; private GameObject stasisWardPrefab; private SkillFamily skillFamily1; private SkillFamily skillFamily2; internal SkillDef skillDef; internal GameObject beaconPrefab; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Lifetime of the T.Beacon: Stasis deployable.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillLifetime { get; private set; } = 15f; [AutoConfigRoOSlider("{0:N0} s", 0f, 120f, null, null)] [AutoConfig("Cooldown of T.Beacon: Stasis.", AutoConfigFlags.DeferForever, new object[] { 0f, float.MaxValue })] public float skillRecharge { get; private set; } = 40f; public override string enabledConfigDescription => "Contains config for the T.Beacon: Stasis submodule of Modules.BeaconRebalance. Does not replace a vanilla beacon."; public override bool managedEnable => false; public BuffDef stasisDebuff { get; private set; } public override void SetupAttributes() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_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_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) base.SetupAttributes(); bool flag = default(bool); SerializableEntityStateType activationState = ContentAddition.AddEntityState(ref flag); SerializableEntityStateType mainStateType = ContentAddition.AddEntityState(ref flag); skillFamily1 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop1SkillFamily"); skillFamily2 = LegacyResourcesAPI.Load("skilldefs/captainbody/CaptainSupplyDrop2SkillFamily"); SkillDef oldDef = LegacyResourcesAPI.Load("skilldefs/captainbody/CallSupplyDropEquipmentRestock"); skillDef = SkillUtil.CloneSkillDef(oldDef); skillDef.rechargeStock = 1; skillDef.baseRechargeInterval = skillRecharge; skillDef.skillName = "AdmiralSupplyDropStasis"; skillDef.skillNameToken = "ADMIRAL_SUPPLY_STASIS_NAME"; skillDef.skillDescriptionToken = "ADMIRAL_SUPPLY_STASIS_DESCRIPTION"; skillDef.icon = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralHeavyWeaponDebuff.png"); skillDef.activationState = activationState; LanguageAPI.Add(skillDef.skillNameToken, "T.Beacon: Stasis"); LanguageAPI.Add(skillDef.skillDescriptionToken, "Temporary beacon. Time-freeze all nearby enemies, preventing them from moving, dealing damage, or taking damage."); ContentAddition.AddSkillDef(skillDef); stasisDebuff = ScriptableObject.CreateInstance(); ((Object)stasisDebuff).name = "Stasis"; stasisDebuff.iconSprite = AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralHeavyWeaponDebuff.png"); stasisDebuff.buffColor = Color.red; stasisDebuff.canStack = false; stasisDebuff.isDebuff = true; ContentAddition.AddBuffDef(stasisDebuff); GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load("prefabs/networkedobjects/captainsupplydrops/CaptainSupplyDrop, EquipmentRestock"), "TempSetup, BeaconPrefabPrefab", false); ((Behaviour)val.GetComponent()).enabled = false; ((Behaviour)val.GetComponent()).enabled = true; CaptainBeaconDecayer captainBeaconDecayer = val.AddComponent(); captainBeaconDecayer.lifetime = skillLifetime; val.GetComponent().mainStateType = mainStateType; beaconPrefab = PrefabAPI.InstantiateClone(val, "AdmiralSupplyDrop, Stasis", true); Object.Destroy((Object)(object)val); GameObject val2 = Object.Instantiate(LegacyResourcesAPI.Load("prefabs/networkedobjects/captainsupplydrops/CaptainHealingWard")); ((Behaviour)val2.GetComponent()).enabled = false; Transform val3 = val2.transform.Find("Indicator"); CaptainBeaconDecayer captainBeaconDecayer2 = val2.AddComponent(); captainBeaconDecayer2.lifetime = skillLifetime - CaptainBeaconDecayer.lifetimeDropAdjust; captainBeaconDecayer2.silent = true; BuffWard val4 = val2.AddComponent(); val4.invertTeamFilter = true; val4.buffDef = stasisDebuff; val4.buffDuration = 2f; val4.radius = 15f; val4.interval = 2f; val4.rangeIndicator = val3; ((Renderer)((Component)val3.Find("IndicatorRing")).GetComponent()).material.SetColor("_TintColor", new Color(0.5f, 0.5f, 1f, 1f)); ParticleSystemRenderer component = ((Component)val3.Find("HealingSymbols")).GetComponent(); ((Renderer)component).material.SetTexture("_MainTex", (Texture)(object)AdmiralPlugin.resources.LoadAsset("Assets/Admiral/Textures/Icons/icon_AdmiralHeavyWeaponDebuff.png").texture); ((Renderer)component).material.SetColor("_TintColor", new Color(0.05f, 0.05f, 2f, 1f)); component.trailMaterial.SetColor("_TintColor", new Color(0.05f, 0.05f, 2f, 1f)); MainModule main = ((Component)val3.Find("Flashes")).GetComponent().main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.25f, 0.25f, 0.5f, 1f)); stasisWardPrefab = PrefabAPI.InstantiateClone(val2, "CaptainStasisWard", true); Object.Destroy((Object)(object)val2); } public override void Install() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown base.Install(); skillFamily1.AddVariant(skillDef); skillFamily2.AddVariant(skillDef); CharacterBody.AddBuff_BuffIndex += new hook_AddBuff_BuffIndex(CharacterBody_AddBuff_BuffIndex); FrozenState.FixedUpdate += new hook_FixedUpdate(FrozenState_FixedUpdate); HealthComponent.TakeDamage += new hook_TakeDamage(HealthComponent_TakeDamage); FrozenState.OnEnter += new hook_OnEnter(FrozenState_OnEnter); } public override void Uninstall() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown base.Uninstall(); skillFamily1.RemoveVariant(skillDef); skillFamily2.RemoveVariant(skillDef); CharacterBody.AddBuff_BuffIndex -= new hook_AddBuff_BuffIndex(CharacterBody_AddBuff_BuffIndex); FrozenState.FixedUpdate -= new hook_FixedUpdate(FrozenState_FixedUpdate); HealthComponent.TakeDamage -= new hook_TakeDamage(HealthComponent_TakeDamage); } private static void CharacterBody_AddBuff_BuffIndex(orig_AddBuff_BuffIndex orig, CharacterBody self, BuffIndex buffType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (buffType == Module.instance.stasisDebuff.buffIndex) { SetStateOnHurt component = ((Component)self).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || !component.canBeFrozen) { return; } component.SetFrozen(2f); } orig.Invoke(self, buffType); } private static void HealthComponent_TakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo) { if (!((Object)(object)self.body != (Object)null) || !self.body.HasBuff(Module.instance.stasisDebuff)) { orig.Invoke(self, damageInfo); } } private void FrozenState_OnEnter(orig_OnEnter orig, FrozenState self) { if (!Object.op_Implicit((Object)(object)((EntityState)self).characterBody) || !((EntityState)self).characterBody.HasBuff(Module.instance.stasisDebuff) || !Object.op_Implicit((Object)(object)((EntityState)self).sfxLocator)) { orig.Invoke(self); return; } string barkSound = ((EntityState)self).sfxLocator.barkSound; ((EntityState)self).sfxLocator.barkSound = ""; orig.Invoke(self); ((EntityState)self).sfxLocator.barkSound = barkSound; } private static void FrozenState_FixedUpdate(orig_FixedUpdate orig, FrozenState self) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); if (!Object.op_Implicit((Object)(object)((EntityState)self).characterBody) || !((EntityState)self).characterBody.HasBuff(Module.instance.stasisDebuff)) { return; } if (Object.op_Implicit((Object)(object)((EntityState)self).rigidbody) && !((EntityState)self).rigidbody.isKinematic) { ((EntityState)self).rigidbody.velocity = Vector3.zero; if (Object.op_Implicit((Object)(object)((EntityState)self).rigidbodyMotor)) { ((EntityState)self).rigidbodyMotor.moveVector = Vector3.zero; } } if (Object.op_Implicit((Object)(object)((EntityState)self).characterMotor)) { ((EntityState)self).characterMotor.velocity = Vector3.zero; } } } public static class SkillUtil { public static void GlobalUpdateSkillDef(SkillDef targetDef) { CharacterMaster.readOnlyInstancesList.Where((CharacterMaster x) => x.hasBody && x.GetBody().healthComponent.alive).ToList().ForEach(delegate(CharacterMaster cb) { if (cb.hasBody) { SkillLocator skillLocator = cb.GetBody().skillLocator; if (Object.op_Implicit((Object)(object)skillLocator)) { for (int i = 0; i < skillLocator.skillSlotCount; i++) { GenericSkill skillAtIndex = skillLocator.GetSkillAtIndex(i); if ((Object)(object)skillAtIndex.skillDef == (Object)(object)targetDef) { skillAtIndex.RecalculateValues(); } } } } }); } public static SkillFamily FindSkillFamilyFromBody(string bodyName, int slotIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_002b: 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) BodyIndex val = BodyCatalog.FindBodyIndex(bodyName); if ((int)val == -1) { AdmiralPlugin._logger.LogError((object)("FindSkillFamilyFromBody: Couldn't find body with name " + bodyName)); return null; } GenericSkill[] bodyPrefabSkillSlots = BodyCatalog.GetBodyPrefabSkillSlots(val); if (slotIndex < 0 || slotIndex > bodyPrefabSkillSlots.Length) { AdmiralPlugin._logger.LogError((object)$"FindSkillFamilyFromBody: Skill slot index {slotIndex} is invalid for body with name {bodyName}"); return null; } return BodyCatalog.GetBodyPrefabSkillSlots(val)[slotIndex].skillFamily; } public static SkillFamily FindSkillFamilyFromBody(string bodyName, SkillSlot slot) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) BodyIndex val = BodyCatalog.FindBodyIndex(bodyName); if ((int)val == -1) { AdmiralPlugin._logger.LogError((object)("FindSkillFamilyFromBody: Couldn't find body with name " + bodyName)); return null; } GenericSkill[] bodyPrefabSkillSlots = BodyCatalog.GetBodyPrefabSkillSlots(val); SkillLocator componentInChildren = BodyCatalog.GetBodyPrefab(val).GetComponentInChildren(); if (!Object.op_Implicit((Object)(object)componentInChildren)) { AdmiralPlugin._logger.LogError((object)("FindSkillFamilyFromBody: Body with name " + bodyName + " has no SkillLocator")); return null; } GenericSkill[] array = bodyPrefabSkillSlots; foreach (GenericSkill val2 in array) { SkillSlot val3 = componentInChildren.FindSkillSlot(val2); if (val3 == slot) { return val2.skillFamily; } } AdmiralPlugin._logger.LogError((object)$"FindSkillFamilyFromBody: Body with name {bodyName} has no skill in slot {slot}"); return null; } public static void ReplaceVariant(this SkillFamily targetFamily, SkillDef origDef, SkillDef newDef) { int num = Array.FindIndex(targetFamily.variants, (Variant x) => (Object)(object)x.skillDef == (Object)(object)origDef); if (num < 0) { AdmiralPlugin._logger.LogError((object)$"SkillFamily.OverrideVariant: couldn't find target skilldef {origDef} in family {targetFamily}"); } else { targetFamily.variants[num].skillDef = newDef; } } public static void ReplaceVariant(string targetBodyName, int targetSlot, SkillDef origDef, SkillDef newDef) { SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.ReplaceVariant(origDef, newDef); } else { AdmiralPlugin._logger.LogError((object)"Failed to OverrideVariant for bodyname+slot (target not found)"); } } public static void ReplaceVariant(string targetBodyName, SkillSlot targetSlot, SkillDef origDef, SkillDef newDef) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.ReplaceVariant(origDef, newDef); } else { AdmiralPlugin._logger.LogError((object)"Failed to OverrideVariant for bodyname+slotname (target not found)"); } } public static void AddVariant(this SkillFamily targetFamily, SkillDef newDef, UnlockableDef unlockableDef = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) Array.Resize(ref targetFamily.variants, targetFamily.variants.Length + 1); Variant[] variants = targetFamily.variants; int num = variants.Length - 1; Variant val = new Variant { skillDef = newDef }; ((Variant)(ref val)).viewableNode = new Node(newDef.skillNameToken, false, (Node)null); val.unlockableDef = unlockableDef; variants[num] = val; } public static void AddVariant(string targetBodyName, int targetSlot, SkillDef newDef, UnlockableDef unlockableDef = null) { SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.AddVariant(newDef, unlockableDef); } else { AdmiralPlugin._logger.LogError((object)"Failed to AddVariant for bodyname+slot (target not found)"); } } public static void AddVariant(string targetBodyName, SkillSlot targetSlot, SkillDef newDef, UnlockableDef unlockableDef = null) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.AddVariant(newDef, unlockableDef); } else { AdmiralPlugin._logger.LogError((object)"Failed to AddVariant for bodyname+slotname (target not found)"); } } public static void RemoveVariant(this SkillFamily targetFamily, SkillDef targetDef) { List list = new List(targetFamily.variants); int count = list.Count; list.RemoveAll((Variant x) => (Object)(object)x.skillDef == (Object)(object)targetDef); if (list.Count - count == 0) { AdmiralPlugin._logger.LogError((object)$"SkillFamily.RemoveVariant: Couldn't find SkillDef {targetDef} for removal from SkillFamily {targetFamily}"); } targetFamily.variants = list.ToArray(); } public static void RemoveVariant(string targetBodyName, int targetSlot, SkillDef targetDef) { SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.RemoveVariant(targetDef); } else { AdmiralPlugin._logger.LogError((object)"Failed to RemoveVariant for bodyname+slot (target not found)"); } } public static void RemoveVariant(string targetBodyName, SkillSlot targetSlot, SkillDef targetDef) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.RemoveVariant(targetDef); } else { AdmiralPlugin._logger.LogError((object)"Failed to RemoveVariant for bodyname+slotname (target not found)"); } } public static SkillDef CloneSkillDef(SkillDef oldDef) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) SkillDef val = ScriptableObject.CreateInstance(); val.skillName = oldDef.skillName; val.skillNameToken = oldDef.skillNameToken; val.skillDescriptionToken = oldDef.skillDescriptionToken; val.icon = oldDef.icon; val.activationStateMachineName = oldDef.activationStateMachineName; val.activationState = oldDef.activationState; val.interruptPriority = oldDef.interruptPriority; val.baseRechargeInterval = oldDef.baseRechargeInterval; val.baseMaxStock = oldDef.baseMaxStock; val.rechargeStock = oldDef.rechargeStock; val.requiredStock = oldDef.requiredStock; val.stockToConsume = oldDef.stockToConsume; val.beginSkillCooldownOnSkillEnd = oldDef.beginSkillCooldownOnSkillEnd; val.fullRestockOnAssign = oldDef.fullRestockOnAssign; val.dontAllowPastMaxStocks = oldDef.dontAllowPastMaxStocks; val.canceledFromSprinting = oldDef.canceledFromSprinting; val.isCombatSkill = oldDef.isCombatSkill; val.resetCooldownTimerOnUse = oldDef.resetCooldownTimerOnUse; val.cancelSprintingOnActivation = oldDef.cancelSprintingOnActivation; val.canceledFromSprinting = oldDef.canceledFromSprinting; val.forceSprintDuringState = oldDef.forceSprintDuringState; val.mustKeyPress = oldDef.mustKeyPress; val.keywordTokens = oldDef.keywordTokens; return val; } }