Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RiskOfTactics v0.1.7
plugins/RiskOfTactics.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG.Reflection; using IL.RoR2; using LookingGlass.ItemStatsNameSpace; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using On.RoR2.UI.LogBook; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RiskOfTactics.Content.Artifacts; using RiskOfTactics.Content.Buffs; using RiskOfTactics.Content.Equipment; using RiskOfTactics.Content.Items.Artifacts; using RiskOfTactics.Content.Items.Completes; using RiskOfTactics.Extensions; using RiskOfTactics.Managers; using RoR2; using RoR2.ExpansionManagement; using RoR2.Items; using RoR2.Orbs; using RoR2.Projectile; using RoR2.UI.LogBook; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RiskOfTactics")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+dc47aeb227c0e20f4f402189db5396cd36afb2ac")] [assembly: AssemblyProduct("RiskOfTactics")] [assembly: AssemblyTitle("RiskOfTactics")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RiskOfTactics { internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("shirograhm.RiskOfTactics", "RiskOfTactics", "0.1.7")] public class RiskOfTactics : BaseUnityPlugin { public const string PluginGUID = "shirograhm.RiskOfTactics"; public const string PluginAuthor = "shirograhm"; public const string PluginName = "RiskOfTactics"; public const string PluginVersion = "0.1.7"; public static ExpansionDef sotvDLC = Addressables.LoadAssetAsync<ExpansionDef>((object)"RoR2/DLC1/Common/DLC1.asset").WaitForCompletion(); public static ExpansionDef sotsDLC = Addressables.LoadAssetAsync<ExpansionDef>((object)"RoR2/DLC2/Common/DLC2.asset").WaitForCompletion(); public static ExpansionDef acDLC = Addressables.LoadAssetAsync<ExpansionDef>((object)"RoR2/DLC3/Common/DLC3.asset").WaitForCompletion(); public static PluginInfo PInfo { get; private set; } public void Awake() { PInfo = ((BaseUnityPlugin)this).Info; Log.Init(((BaseUnityPlugin)this).Logger); AssetManager.Init(); GameEventManager.Init(); ConfigOptions.Init(); Utilities.Init(); ((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)Integrations.Init); Sunder.Init(); if (AdaptiveHelm.isEnabled.Value) { AdaptiveHelm.Init(); } if (ArchangelsStaff.isEnabled.Value) { ArchangelsStaff.Init(); } if (Bloodthirster.isEnabled.Value) { Bloodthirster.Init(); } if (BrambleVest.isEnabled.Value) { BrambleVest.Init(); } if (Crownguard.isEnabled.Value) { Crownguard.Init(); } if (DragonsClaw.isEnabled.Value) { DragonsClaw.Init(); } if (GuinsoosRageblade.isEnabled.Value) { GuinsoosRageblade.Init(); } if (HandOfJustice.isEnabled.Value) { HandOfJustice.Init(); } if (HextechGunblade.isEnabled.Value) { HextechGunblade.Init(); } if (Quicksilver.isEnabled.Value) { Quicksilver.Init(); } if (StrikersFlail.isEnabled.Value) { StrikersFlail.Init(); } if (SpearOfShojin.isEnabled.Value) { SpearOfShojin.Init(); } if (SunfireCape.isEnabled.Value) { SunfireCape.Init(); } if (TitansResolve.isEnabled.Value) { TitansResolve.Init(); } if (WarmogsArmor.isEnabled.Value) { WarmogsArmor.Init(); } if (GamblersBlade.isEnabled.Value) { GamblersBlade.Init(); } if (HellfireHatchet.isEnabled.Value) { HellfireHatchet.Init(); } if (HorizonFocus.isEnabled.Value) { HorizonFocus.Init(); } if (LightshieldCrest.isEnabled.Value) { LightshieldCrest.Init(); } if (Mittens.isEnabled.Value) { Mittens.Init(); } if (SnipersFocus.isEnabled.Value) { SnipersFocus.Init(); } if (StatikkShiv.isEnabled.Value) { StatikkShiv.Init(); } if (ZhonyasParadox.isEnabled.Value) { ZhonyasParadox.Init(); } if (LuckyItemChest.isEnabled.Value) { LuckyItemChest.Init(); } if (ArtifactOfTheGoldenSpat.isEnabled.Value) { ArtifactOfTheGoldenSpat.Init(); } if ((bool)ConfigManager.Scaling.useRadiantAutoConversion) { InjectRadiantItemTramsforms(); } Log.Message("Finished initializations."); } private void InjectRadiantItemTramsforms() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) ItemRelationshipProvider val = ScriptableObject.CreateInstance<ItemRelationshipProvider>(); ((Object)val).name = "RiskOfTactics_RadiantItemProvider"; val.relationshipType = Addressables.LoadAssetAsync<ItemRelationshipType>((object)"RoR2/DLC1/Common/ContagiousItem.asset").WaitForCompletion(); val.relationships = Utilities.GetRadiantUpgradePairs(); if (ContentAddition.AddItemRelationshipProvider(val)) { Log.Debug("Successfully injected radiant item transformations."); } else { Log.Error("Unable to inject radiant item transformations."); } } } public static class Utilities { private class SyncForceRecalculate : INetMessage, ISerializableObject { private NetworkInstanceId netID; public SyncForceRecalculate() { } public SyncForceRecalculate(NetworkInstanceId ID) { //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) netID = ID; } public void Deserialize(NetworkReader reader) { //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) netID = reader.ReadNetworkId(); } public void OnReceived() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } GameObject val = Util.FindNetworkObject(netID); if (Object.op_Implicit((Object)(object)val)) { CharacterBody component = val.GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component)) { component.RecalculateStats(); } } } public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) writer.Write(netID); writer.FinishMessage(); } } public static List<Pair> radiantPairs = new List<Pair>(); internal static void Init() { NetworkingAPI.RegisterMessageType<SyncForceRecalculate>(); } public static void ForceRecalculate(CharacterBody body) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) body.RecalculateStats(); if (NetworkServer.active) { new SyncForceRecalculate(((NetworkBehaviour)body).netId); } } public static CharacterBody GetMinionOwnershipParentBody(CharacterBody body) { if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.master) && Object.op_Implicit((Object)(object)body.master.minionOwnership) && Object.op_Implicit((Object)(object)body.master.minionOwnership.ownerMaster) && Object.op_Implicit((Object)(object)body.master.minionOwnership.ownerMaster.GetBody())) { return body.master.minionOwnership.ownerMaster.GetBody(); } return body; } public static CharacterBody GetLowestHealthAlly(TeamIndex index) { //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) IEnumerable<CharacterMaster> source = CharacterMaster.readOnlyInstancesList.Where((CharacterMaster el) => el.teamIndex == index); CharacterMaster val = source.OrderBy((CharacterMaster el) => (!Object.op_Implicit((Object)(object)el.GetBody())) ? 1f : (Object.op_Implicit((Object)(object)el.GetBody().healthComponent) ? el.GetBody().healthComponent.combinedHealthFraction : 1f)).FirstOrDefault(); return Object.op_Implicit((Object)(object)val) ? val.GetBody() : null; } public static uint ScaleGoldWithDifficulty(int goldGranted) { return Convert.ToUInt32((float)goldGranted * (1f + 50f * GetDifficultyAsPercentage())); } public static float GetChanceAfterLuck(float percent, float luckIn) { int num = Mathf.CeilToInt(luckIn); if (num > 0) { return 1f - Mathf.Pow(1f - percent, (float)(num + 1)); } if (num < 0) { return Mathf.Pow(percent, (float)(Mathf.Abs(num) + 1)); } return percent; } public static bool IsMeleeBodyPrefab(GameObject bodyPrefab) { if (!Object.op_Implicit((Object)(object)bodyPrefab)) { return false; } string text = ((Object)bodyPrefab).name; if (text.Contains("(Clone)")) { text = text.Replace("(Clone)", ""); } string[] source = ConfigManager.Scaling.meleeCharactersList.Value.Split(','); return source.Contains(text); } public static bool IsRangedBodyPrefab(GameObject bodyPrefab) { if (!Object.op_Implicit((Object)(object)bodyPrefab)) { return false; } string text = ((Object)bodyPrefab).name; if (text.Contains("(Clone)")) { text = text.Replace("(Clone)", ""); } string[] source = ConfigManager.Scaling.rangedCharactersList.Value.Split(','); return source.Contains(text); } public static float GetMissingHealth(HealthComponent healthComponent, bool includeShield) { if (includeShield) { return healthComponent.fullCombinedHealth * (1f - healthComponent.combinedHealthFraction); } return healthComponent.fullHealth * (1f - healthComponent.healthFraction); } public static float GetMissingHealthPercent(HealthComponent healthComponent, bool includeShield) { if (includeShield) { return 100f * (1f - healthComponent.combinedHealthFraction); } return 100f * (1f - healthComponent.healthFraction); } public static float GetDifficultyAsPercentage() { return (Stage.instance.entryDifficultyCoefficient - 1f) / 98f; } public static float GetDifficultyAsMultiplier() { return Stage.instance.entryDifficultyCoefficient; } public static float GetLinearStacking(float baseValue, int count) { return GetLinearStacking(baseValue, baseValue, count); } public static float GetLinearStacking(float baseValue, float extraValue, int count) { return baseValue + extraValue * (float)(count - 1); } public static float GetExponentialStacking(float percent, int count) { return GetExponentialStacking(percent, percent, count); } public static float GetExponentialStacking(float percent, float stackPercent, int count) { return 1f - (1f - percent) * Mathf.Pow(1f - stackPercent, (float)(count - 1)); } public static float GetReverseExponentialStacking(float baseValue, float reducePercent, int count) { return baseValue * Mathf.Pow(1f - reducePercent, (float)(count - 1)); } public static float GetHyperbolicStacking(float percent, int count) { return GetHyperbolicStacking(percent, percent, count); } public static float GetHyperbolicStacking(float percent, float extraPercent, int count) { float num = (1f + percent) * (1f + extraPercent * (float)(count - 1)); return 1f - 1f / num; } internal static BuffDef GenerateBuffDef(string name, Sprite sprite, bool canStack, bool isHidden, bool isDebuff, bool isCooldown) { BuffDef val = ScriptableObject.CreateInstance<BuffDef>(); ((Object)val).name = name; val.iconSprite = sprite; val.canStack = canStack; val.isHidden = isHidden; val.isDebuff = isDebuff; val.isCooldown = isCooldown; return val; } internal static bool OnSameTeam(CharacterBody body1, CharacterBody body2) { //IL_0021: 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) return Object.op_Implicit((Object)(object)body1.teamComponent) && Object.op_Implicit((Object)(object)body2.teamComponent) && body1.teamComponent.teamIndex == body2.teamComponent.teamIndex; } internal static bool IsValidTargetBody(CharacterBody body) { return Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent); } internal static void SpawnHealEffect(CharacterBody self) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown EffectData val = new EffectData { origin = self.transform.position, rootObject = ((Component)self).gameObject }; EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/MedkitHealEffect"), val, true); } internal static void SpawnGoldPack(CharacterBody attacker, CharacterBody victim, float moneyGain) { //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) //IL_0072: 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) GameObject val = Object.Instantiate<GameObject>(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/BonusMoneyPack"), victim.transform.position, Random.rotation); if (!Object.op_Implicit((Object)(object)val)) { return; } Collider component = val.GetComponent<Collider>(); if (Object.op_Implicit((Object)(object)component)) { TeamFilter component2 = val.GetComponent<TeamFilter>(); if (Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)attacker.teamComponent)) { component2.teamIndex = attacker.teamComponent.teamIndex; } MoneyPickup componentInChildren = val.GetComponentInChildren<MoneyPickup>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.baseGoldReward = Mathf.RoundToInt(moneyGain * GetDifficultyAsMultiplier()); Physics.IgnoreCollision(component, ((Component)componentInChildren).GetComponent<Collider>()); } GravitatePickup componentInChildren2 = val.GetComponentInChildren<GravitatePickup>(); if (Object.op_Implicit((Object)(object)componentInChildren2)) { Physics.IgnoreCollision(component, ((Component)componentInChildren2).GetComponent<Collider>()); } val.transform.localScale = new Vector3(0.65f, 4.5f, 0.25f); NetworkServer.Spawn(val); } } internal static void UpdateSingleTemporaryVisualEffect(ref TemporaryVisualEffect tempEffect, GameObject tempEffectPrefab, CharacterBody userBody, bool active, string childLocatorOverride = "") { //IL_00ff: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tempEffect != (Object)null != active) { if (active && Object.op_Implicit((Object)(object)tempEffectPrefab)) { GameObject val = Object.Instantiate<GameObject>(tempEffectPrefab, userBody.corePosition, Quaternion.identity); tempEffect = val.GetComponent<TemporaryVisualEffect>(); tempEffect.parentTransform = userBody.coreTransform; tempEffect.visualState = (VisualState)0; tempEffect.healthComponent = userBody.healthComponent; tempEffect.radius = 1f; LocalCameraEffect component = val.GetComponent<LocalCameraEffect>(); if (Object.op_Implicit((Object)(object)component)) { component.targetCharacter = ((Component)userBody).gameObject; } if (!string.IsNullOrEmpty(childLocatorOverride)) { ModelLocator modelLocator = userBody.modelLocator; object obj; if (modelLocator == null) { obj = null; } else { Transform modelTransform = modelLocator.modelTransform; obj = ((modelTransform != null) ? ((Component)modelTransform).GetComponent<ChildLocator>() : null); } ChildLocator val2 = (ChildLocator)obj; if (Object.op_Implicit((Object)(object)val2)) { Transform val3 = val2.FindChild(childLocatorOverride); if (Object.op_Implicit((Object)(object)val3)) { tempEffect.parentTransform = val3; } } } } else { tempEffect.visualState = (VisualState)1; } } if ((Object)(object)tempEffect != (Object)null) { bool active2 = (Object)(object)userBody.currentVehicle == (Object)null || !userBody.currentVehicle.hidePassenger; if (Object.op_Implicit((Object)(object)tempEffect.visualTransform)) { ((Component)tempEffect.visualTransform).gameObject.SetActive(active2); } } } public static Pair[] GetRadiantUpgradePairs() { return radiantPairs.ToArray(); } internal static void RegisterRadiantUpgrade(ItemDef itemDef, ItemDef radiantDef) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) radiantPairs.Add(new Pair { itemDef1 = itemDef, itemDef2 = radiantDef }); } } } namespace RiskOfTactics.Managers { public static class AssetManager { public static AssetBundle bundle; public const string bundleName = "rotassets"; public static string AssetBundlePath => Path.Combine(Path.GetDirectoryName(RiskOfTactics.PInfo.Location), "rotassets"); public static void Init() { bundle = AssetBundle.LoadFromFile(AssetBundlePath); } } public static class ConfigManager { public static class Scaling { public static ConfigFile config = new ConfigFile(Paths.ConfigPath + "\\RiskOfTactics.cfg", true); public static string categoryName = "RiskOfTactics Config"; public static string categoryGUID = "shirograhm.RiskOfTactics_config"; public static ConfigOptions.ConfigurableValue<bool> useCustomValues = ConfigOptions.ConfigurableValue.CreateBool(categoryGUID, categoryName, config, "! Important !", "Use Custom Configs", defaultValue: false, "Set to true to enable the custom config values below."); public static ConfigOptions.ConfigurableValue<string> meleeCharactersList = ConfigOptions.ConfigurableValue.CreateString(categoryGUID, categoryName, config, "! Important !", "Melee Characters", "MercBody,LoaderBody,CrocoBody,FalseSonBody,Executioner2Body,NemCommandoBody", "List of melee characters. Add modded charater bodies here to enable selective item effects (e.g. Adaptive Helm)."); public static ConfigOptions.ConfigurableValue<string> rangedCharactersList = ConfigOptions.ConfigurableValue.CreateString(categoryGUID, categoryName, config, "! Important !", "Ranged Characters", "CommandoBody,HuntressBody,Bandit2Body,ToolbotBody,EngiBody,EngiTurretBody,MageBody,TreebotBody,CaptainBody,RailGunnerBody,VoidSurvivorBody,SeekerBody,ChefBody,ScavBody,RangerBody,ChirrBody,ElectricianBody", "List of ranged characters. Add modded charater bodies here to enable selective item effects (e.g. Adaptive Helm)."); public static ConfigOptions.ConfigurableValue<float> radiantItemStatMultiplier = ConfigOptions.ConfigurableValue.CreateFloat(categoryGUID, categoryName, config, "! Important !", "Radiant Stat Multiplier", 2f, 1f, 1000000f, "Value all stats are multiplied by when upgraded to radiant."); public static ConfigOptions.ConfigurableValue<bool> useRadiantAutoConversion = ConfigOptions.ConfigurableValue.CreateBool(categoryGUID, categoryName, config, "! Important !", "Radiant Auto-Conversion", defaultValue: true, "Set to true to enable automatic conversion of items to their radiant versions if you have both in your inventory. WARNING: Disabling this may cause bugs."); } } public class ConfigurableValue<T> : ConfigOptions.ConfigurableValue<T> { public ConfigurableValue(string section, string key, float defaultValue, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, Action<float> onChanged = null) : base(ConfigManager.Scaling.config, section, key, (T)Convert.ChangeType(defaultValue, typeof(T)), description, stringsToAffect, isRadiantStat, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, (Action<T>)null) { ConfigOptions.ConfigurableValue.CreateFloat(ConfigManager.Scaling.categoryGUID, ConfigManager.Scaling.categoryName, ConfigManager.Scaling.config, section, key, defaultValue, 0f, 1000000f, description, stringsToAffect, isRadiantStat, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, onChanged); } public ConfigurableValue(string section, string key, int defaultValue, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, Action<int> onChanged = null) : base(ConfigManager.Scaling.config, section, key, (T)Convert.ChangeType(defaultValue, typeof(T)), description, stringsToAffect, isRadiantStat, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, (Action<T>)null) { ConfigOptions.ConfigurableValue.CreateInt(ConfigManager.Scaling.categoryGUID, ConfigManager.Scaling.categoryName, ConfigManager.Scaling.config, section, key, defaultValue, 0, 1000000, description, stringsToAffect, isRadiantStat, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, onChanged); } public ConfigurableValue(string section, string key, bool defaultValue, string description = "", List<string> stringsToAffect = null, Action<bool> onChanged = null) : base(ConfigManager.Scaling.config, section, key, (T)Convert.ChangeType(defaultValue, typeof(T)), description, stringsToAffect, isRadiantStat: false, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, (Action<T>)null) { ConfigOptions.ConfigurableValue.CreateBool(ConfigManager.Scaling.categoryGUID, ConfigManager.Scaling.categoryName, ConfigManager.Scaling.config, section, key, defaultValue, description, stringsToAffect, isRadiantStat: false, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, onChanged); } public ConfigurableValue(string section, string key, string defaultValue, string description = "", List<string> stringsToAffect = null, Action<string> onChanged = null) : base(ConfigManager.Scaling.config, section, key, (T)Convert.ChangeType(defaultValue, typeof(T)), description, stringsToAffect, isRadiantStat: false, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, (Action<T>)null) { ConfigOptions.ConfigurableValue.CreateString(ConfigManager.Scaling.categoryGUID, ConfigManager.Scaling.categoryName, ConfigManager.Scaling.config, section, key, defaultValue, description, stringsToAffect, isRadiantStat: false, ConfigManager.Scaling.useCustomValues.bepinexConfigEntry, restartRequired: false, onChanged); } } public static class ConfigOptions { public abstract class ConfigurableValue { public static List<ConfigurableValue> instancesList = new List<ConfigurableValue>(); public List<string> stringsToAffect = new List<string>(); public bool isRadiantStat = false; public string key = ""; public string id = ""; public static ConfigurableValue<T> Create<T>(ConfigFile configFile, string section, string key, T defaultValue, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, ConfigEntry<bool> useCustomValueConfigEntry = null, bool restartRequired = false, Action<T> onChanged = null) { return new ConfigurableValue<T>(configFile, section, key, defaultValue, description, stringsToAffect, isRadiantStat, useCustomValueConfigEntry, restartRequired, onChanged); } public static ConfigurableValue<int> CreateInt(string modGUID, string modName, ConfigFile configFile, string section, string key, int defaultValue, int min = 0, int max = 1000, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, ConfigEntry<bool> useCustomValueConfigEntry = null, bool restartRequired = false, Action<int> onChanged = null) { return Create(configFile, section, key, defaultValue, description, stringsToAffect, isRadiantStat, useCustomValueConfigEntry, restartRequired, onChanged); } public static ConfigurableValue<float> CreateFloat(string modGUID, string modName, ConfigFile configFile, string section, string key, float defaultValue, float min = 0f, float max = 1000f, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, ConfigEntry<bool> useCustomValueConfigEntry = null, bool restartRequired = false, Action<float> onChanged = null) { return Create(configFile, section, key, defaultValue, description, stringsToAffect, isRadiantStat, useCustomValueConfigEntry, restartRequired, onChanged); } public static ConfigurableValue<bool> CreateBool(string modGUID, string modName, ConfigFile configFile, string section, string key, bool defaultValue, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, ConfigEntry<bool> useCustomValueConfigEntry = null, bool restartRequired = false, Action<bool> onChanged = null) { return Create(configFile, section, key, defaultValue, description, stringsToAffect, isRadiantStat, useCustomValueConfigEntry, restartRequired, onChanged); } public static ConfigurableValue<string> CreateString(string modGUID, string modName, ConfigFile configFile, string section, string key, string defaultValue, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, ConfigEntry<bool> useCustomValueConfigEntry = null, bool restartRequired = false, Action<string> onChanged = null) { return Create(configFile, section, key, defaultValue, description, stringsToAffect, isRadiantStat, useCustomValueConfigEntry, restartRequired, onChanged); } } public class ConfigurableValue<T> : ConfigurableValue { public ConfigEntry<T> bepinexConfigEntry; private ConfigEntry<bool> useCustomValueConfigEntry; private T defaultValue; public T Value { get { if (useCustomValueConfigEntry != null && useCustomValueConfigEntry.Value) { return bepinexConfigEntry.Value; } return defaultValue; } } public ConfigurableValue(ConfigFile configFile, string section, string key, T defaultValue, string description = "", List<string> stringsToAffect = null, bool isRadiantStat = false, ConfigEntry<bool> useCustomValueConfigEntry = null, bool restartRequired = false, Action<T> onChanged = null) { ConfigurableValue<T> configurableValue = this; id = Path.GetFileNameWithoutExtension(configFile.ConfigFilePath) + "." + section + "." + key; ConfigurableValue configurableValue2 = ConfigurableValue.instancesList.FirstOrDefault((ConfigurableValue x) => x.id == configurableValue.id); if (configurableValue2 != null) { ConfigurableValue<T> configurableValue3 = configurableValue2 as ConfigurableValue<T>; bepinexConfigEntry = configurableValue3.bepinexConfigEntry; this.useCustomValueConfigEntry = useCustomValueConfigEntry; } else { bepinexConfigEntry = configFile.Bind<T>(section, key, defaultValue, description); ConfigurableValue.instancesList.Add(this); } this.useCustomValueConfigEntry = useCustomValueConfigEntry; base.key = key; this.defaultValue = defaultValue; base.isRadiantStat = isRadiantStat; if (stringsToAffect != null) { base.stringsToAffect = stringsToAffect; } else { base.stringsToAffect = new List<string>(); } if (onChanged != null) { bepinexConfigEntry.SettingChanged += delegate { onChanged(configurableValue.bepinexConfigEntry.Value); reloadLogbook = true; }; onChanged(bepinexConfigEntry.Value); reloadLogbook = true; } } public override string ToString() { return Convert.ToString(Value, CultureInfo.InvariantCulture); } public static implicit operator T(ConfigurableValue<T> configurableValue) { return configurableValue.Value; } } [CompilerGenerated] private static class <>O { public static hook_Awake <0>__LogBookController_Awake; public static hook_GetLocalizedStringByToken <1>__Language_GetLocalizedStringByToken; } private static bool reloadLogbook; internal static void Init() { //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) //IL_001c: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown object obj = <>O.<0>__LogBookController_Awake; if (obj == null) { hook_Awake val = LogBookController_Awake; <>O.<0>__LogBookController_Awake = val; obj = (object)val; } LogBookController.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__Language_GetLocalizedStringByToken; if (obj2 == null) { hook_GetLocalizedStringByToken val2 = Language_GetLocalizedStringByToken; <>O.<1>__Language_GetLocalizedStringByToken = val2; obj2 = (object)val2; } Language.GetLocalizedStringByToken += (hook_GetLocalizedStringByToken)obj2; } private static void LogBookController_Awake(orig_Awake orig, LogBookController self) { orig.Invoke(self); if (reloadLogbook) { reloadLogbook = false; LogBookController.BuildStaticData(); } } private static string Language_GetLocalizedStringByToken(orig_GetLocalizedStringByToken orig, Language self, string token) { string text = orig.Invoke(self, token); bool flag = token.Contains("RADIANT_"); foreach (ConfigurableValue item in ConfigurableValue.instancesList.FindAll((ConfigurableValue x) => x.stringsToAffect.Contains(token.Replace("RADIANT_", "")))) { string newValue; if (flag && item.isRadiantStat) { if (1 == 0) { } string text2 = ((item is ConfigurableValue<float> configurableValue) ? (configurableValue.Value * (float)ConfigManager.Scaling.radiantItemStatMultiplier).ToString() : ((!(item is ConfigurableValue<int> configurableValue2)) ? item.ToString() : ((float)configurableValue2.Value * (float)ConfigManager.Scaling.radiantItemStatMultiplier).ToString())); if (1 == 0) { } newValue = text2; } else { newValue = item.ToString(); } text = text.Replace("{" + item.key + "}", newValue); text = text.Replace("{Sunder Reduction}", Sunder.armorReduction.Value.ToString()); } return text; } } internal class GameEventManager { public delegate void DamageAttackerVictimEventHandler(DamageInfo damageInfo, GenericCharacterInfo attackerInfo, GenericCharacterInfo victimInfo); public delegate void DamageReportEventHandler(DamageReport damageReport); public struct GenericCharacterInfo { public GameObject gameObject; public CharacterBody body; public CharacterMaster master; public TeamComponent teamComponent; public HealthComponent healthComponent; public Inventory inventory; public TeamIndex teamIndex; public Vector3 aimOrigin; public unsafe GenericCharacterInfo(CharacterBody body) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00a1->IL00a1: Incompatible stack types: Ref vs I4 //IL_0096->IL00a1: Incompatible stack types: I4 vs Ref //IL_0096->IL00a1: Incompatible stack types: Ref vs I4 this.body = body; gameObject = (Object.op_Implicit((Object)(object)body) ? ((Component)body).gameObject : null); master = (Object.op_Implicit((Object)(object)body) ? body.master : null); teamComponent = (Object.op_Implicit((Object)(object)body) ? body.teamComponent : null); healthComponent = (Object.op_Implicit((Object)(object)body) ? body.healthComponent : null); inventory = (Object.op_Implicit((Object)(object)master) ? master.inventory : null); ref GenericCharacterInfo reference = ref this; int num; if (Object.op_Implicit((Object)(object)teamComponent)) { reference = ref *(GenericCharacterInfo*)teamComponent.teamIndex; num = (int)(ref reference); } else { num = 0; reference = ref *(GenericCharacterInfo*)num; num = (int)(ref reference); } Unsafe.Write(&((GenericCharacterInfo*)num)->teamIndex, (TeamIndex)(ref reference)); Vector3 normalized; if (!Object.op_Implicit((Object)(object)body)) { Vector3 insideUnitSphere = Random.insideUnitSphere; normalized = ((Vector3)(ref insideUnitSphere)).normalized; } else { normalized = body.aimOrigin; } aimOrigin = normalized; } } public class GenericDamageEvent : MonoBehaviour, IOnIncomingDamageServerReceiver, IOnTakeDamageServerReceiver { public HealthComponent healthComponent; public CharacterBody victimBody; public void Start() { healthComponent = ((Component)this).GetComponent<HealthComponent>(); if (!Object.op_Implicit((Object)(object)healthComponent)) { Object.Destroy((Object)(object)this); } else { victimBody = healthComponent.body; } } public void OnIncomingDamageServer(DamageInfo damageInfo) { GenericCharacterInfo attackerInfo = default(GenericCharacterInfo); if (Object.op_Implicit((Object)(object)damageInfo.attacker)) { attackerInfo = new GenericCharacterInfo(damageInfo.attacker.GetComponent<CharacterBody>()); } GenericCharacterInfo victimInfo = new GenericCharacterInfo(victimBody); GameEventManager.BeforeTakeDamage?.Invoke(damageInfo, attackerInfo, victimInfo); } public void OnTakeDamageServer(DamageReport damageReport) { if (Object.op_Implicit((Object)(object)victimBody) && GameEventManager.OnTakeDamage != null) { GameEventManager.OnTakeDamage(damageReport); } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_Awake <>9__12_0; public static hook_OnHitEnemy <>9__12_1; internal void <Init>b__12_0(orig_Awake orig, HealthComponent self) { ((Component)self).gameObject.AddComponent<GenericDamageEvent>(); orig.Invoke(self); } internal void <Init>b__12_1(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo damageInfo, GameObject victim) { orig.Invoke(self, damageInfo, victim); if (Object.op_Implicit((Object)(object)damageInfo.attacker)) { CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>(); CharacterBody body = (Object.op_Implicit((Object)(object)victim) ? victim.GetComponent<CharacterBody>() : null); GenericCharacterInfo attackerInfo = new GenericCharacterInfo(component); GenericCharacterInfo victimInfo = new GenericCharacterInfo(body); GameEventManager.OnHitEnemy?.Invoke(damageInfo, attackerInfo, victimInfo); } } } public static event DamageAttackerVictimEventHandler OnHitEnemy; public static event DamageAttackerVictimEventHandler BeforeTakeDamage; public static event DamageReportEventHandler OnTakeDamage; internal static void Init() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_003a: 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_0045: Expected O, but got Unknown object obj = <>c.<>9__12_0; if (obj == null) { hook_Awake val = delegate(orig_Awake orig, HealthComponent self) { ((Component)self).gameObject.AddComponent<GenericDamageEvent>(); orig.Invoke(self); }; <>c.<>9__12_0 = val; obj = (object)val; } HealthComponent.Awake += (hook_Awake)obj; object obj2 = <>c.<>9__12_1; if (obj2 == null) { hook_OnHitEnemy val2 = delegate(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo damageInfo, GameObject victim) { orig.Invoke(self, damageInfo, victim); if (Object.op_Implicit((Object)(object)damageInfo.attacker)) { CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>(); CharacterBody body = (Object.op_Implicit((Object)(object)victim) ? victim.GetComponent<CharacterBody>() : null); GenericCharacterInfo attackerInfo = new GenericCharacterInfo(component); GenericCharacterInfo victimInfo = new GenericCharacterInfo(body); GameEventManager.OnHitEnemy?.Invoke(damageInfo, attackerInfo, victimInfo); } }; <>c.<>9__12_1 = val2; obj2 = (object)val2; } GlobalEventManager.OnHitEnemy += (hook_OnHitEnemy)obj2; } } public static class ItemManager { public enum TacticTier { Normal, Radiant, Artifact } public static List<ItemDef> normalList = new List<ItemDef>(); public static List<ItemDef> radiantList = new List<ItemDef>(); public static List<ItemDef> artifactList = new List<ItemDef>(); public static ItemDef GenerateItem(string name, ItemTag[] tags, TacticTier tTier) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) ItemDef val = ScriptableObject.CreateInstance<ItemDef>(); ((Object)val).name = "ROT_" + name.ToUpperInvariant(); val.AutoPopulateTokens(); SetItemTier(val, GetTierFromTacticTier(tTier)); GameObject val2 = AssetManager.bundle.LoadAsset<GameObject>(name + ".prefab"); if ((Object)(object)val2 == (Object)null) { Log.Warning("Missing prefab file for item " + ((Object)val).name + ". Substituting default..."); val2 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Mystery/PickupMystery.prefab").WaitForCompletion(); } ModelPanelParameters val3 = val2.AddComponent<ModelPanelParameters>(); val3.focusPointTransform = val2.transform; val3.cameraPositionTransform = val2.transform; val3.maxDistance = 10f; val3.minDistance = 5f; val.pickupIconSprite = AssetManager.bundle.LoadAsset<Sprite>(name + ".png"); val.pickupModelPrefab = val2; val.canRemove = true; val.hidden = false; val.tags = tags; ItemDisplayRuleDict val4 = new ItemDisplayRuleDict((ItemDisplayRule[])null); ItemAPI.Add(new CustomItem(val, val4)); switch (tTier) { case TacticTier.Normal: normalList.Add(val); break; case TacticTier.Radiant: radiantList.Add(val); break; case TacticTier.Artifact: artifactList.Add(val); break; } return val; } public static EquipmentDef GenerateEquipment(string name, float cooldown, bool isLunar = false, bool appearsInMultiPlayer = true, bool appearsInSinglePlayer = true, bool canBeRandomlyTriggered = true, bool enigmaCompatible = true, bool canDrop = true) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) EquipmentDef val = ScriptableObject.CreateInstance<EquipmentDef>(); ((Object)val).name = "ROT_" + name.ToUpperInvariant(); val.AutoPopulateTokens(); GameObject val2 = AssetManager.bundle.LoadAsset<GameObject>(name + ".prefab"); if ((Object)(object)val2 == (Object)null) { Log.Warning("Missing prefab file for equipment " + ((Object)val).name + ". Substituting default..."); val2 = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Mystery/PickupMystery.prefab").WaitForCompletion(); } ModelPanelParameters val3 = val2.AddComponent<ModelPanelParameters>(); val3.focusPointTransform = val2.transform; val3.cameraPositionTransform = val2.transform; val3.maxDistance = 10f; val3.minDistance = 5f; val.pickupIconSprite = AssetManager.bundle.LoadAsset<Sprite>(name + ".png"); val.pickupModelPrefab = val2; val.isLunar = isLunar; if (isLunar) { val.colorIndex = (ColorIndex)4; } val.appearsInMultiPlayer = appearsInMultiPlayer; val.appearsInSinglePlayer = appearsInSinglePlayer; val.canBeRandomlyTriggered = canBeRandomlyTriggered; val.enigmaCompatible = enigmaCompatible; val.canDrop = canDrop; val.cooldown = cooldown; ItemDisplayRuleDict val4 = new ItemDisplayRuleDict((ItemDisplayRule[])null); ItemAPI.Add(new CustomEquipment(val, val4)); return val; } public static ItemTier GetTierFromTacticTier(TacticTier tier) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (1 == 0) { } ItemTier result = (ItemTier)(tier switch { TacticTier.Normal => 1, TacticTier.Radiant => 4, TacticTier.Artifact => 2, _ => 5, }); if (1 == 0) { } return result; } public static ItemDef GetRandomTacticItemOfTier(TacticTier tier) { if (1 == 0) { } ItemDef result = (ItemDef)(tier switch { TacticTier.Normal => normalList[Random.Range(0, normalList.Count)], TacticTier.Radiant => radiantList[Random.Range(0, radiantList.Count)], TacticTier.Artifact => artifactList[Random.Range(0, artifactList.Count)], _ => null, }); if (1 == 0) { } return result; } public static void SetItemTier(ItemDef itemDef, ItemTier tier) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_002b: 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) if ((int)tier == 5) { try { itemDef.deprecatedTier = tier; } catch (Exception arg) { Log.Warning($"Error setting deprecatedTier for {((Object)itemDef).name}: {arg}"); } } ((ResourceAvailability)(ref ItemTierCatalog.availability)).CallWhenAvailable((Action)delegate { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)itemDef)) { itemDef.tier = tier; } }); } } internal class SoundManager { public static uint zhonyas_SFX_ID = 3923907719u; } } namespace RiskOfTactics.Extensions { internal class Integrations { internal static bool lookingGlassEnabled; internal static void Init() { Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos; if (pluginInfos.ContainsKey("droppod.lookingglass")) { try { Log.Debug("Running code injection for LookingGlass."); LookingGlassIntegration.Init(); lookingGlassEnabled = true; } catch (Exception data) { Log.Error(data); } } } } internal static class LookingGlassIntegration { public static class LookingGlassStats { private readonly struct ItemStatLine { public string Name { get; } public ValueType ValueType { get; } public MeasurementUnits Units { get; } public ItemStatLine(string n, ValueType v, MeasurementUnits u) { //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_000f: 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) Name = n; ValueType = v; Units = u; } } public static void RegisterStats() { if (BrambleVest.isEnabled.Value) { RegisterStatsForItemWithRadiantVariant(BrambleVest.itemDef, BrambleVest.radiantDef, new List<ItemStatLine>(1) { new ItemStatLine("Damage Reflected: ", (ValueType)1, (MeasurementUnits)4) }, delegate(CharacterMaster master, int itemCount) { List<float> list3 = new List<float>(); if (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory) && Object.op_Implicit((Object)(object)((Component)master.inventory).GetComponent<BrambleVest.Statistics>())) { list3.Add(((Component)master.inventory).GetComponent<BrambleVest.Statistics>().DamageReflected); } else { list3.Add(0f); } return list3; }); } if (HextechGunblade.isEnabled.Value) { RegisterStatsForItemWithRadiantVariant(HextechGunblade.itemDef, HextechGunblade.radiantDef, new List<ItemStatLine>(1) { new ItemStatLine("Total Healing: ", (ValueType)0, (MeasurementUnits)4) }, delegate(CharacterMaster master, int itemCount) { List<float> list2 = new List<float>(); if (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory) && Object.op_Implicit((Object)(object)((Component)master.inventory).GetComponent<HextechGunblade.Statistics>())) { list2.Add(((Component)master.inventory).GetComponent<HextechGunblade.Statistics>().DamageHealed); } else { list2.Add(0f); } return list2; }); } if (SpearOfShojin.isEnabled.Value) { RegisterStatsForItem(SpearOfShojin.itemDef, new List<ItemStatLine>(1) { new ItemStatLine("On-Hit Reduction: ", (ValueType)2, (MeasurementUnits)1) }, (CharacterMaster master, int itemCount) => new List<float>(1) { Utilities.GetHyperbolicStacking(SpearOfShojin.percentCooldownOnHit, SpearOfShojin.percentCooldownOnHitExtraStacks, itemCount) }); RegisterStatsForItem(SpearOfShojin.radiantDef, new List<ItemStatLine>(1) { new ItemStatLine("On-Hit Reduction: ", (ValueType)2, (MeasurementUnits)1) }, (CharacterMaster master, int itemCount) => new List<float>(1) { Utilities.GetHyperbolicStacking(SpearOfShojin.percentCooldownOnHit, SpearOfShojin.percentCooldownOnHitExtraStacks, itemCount) * PercentRadiantItemStatMultiplier }); } if (WarmogsArmor.isEnabled.Value) { RegisterStatsForItem(WarmogsArmor.itemDef, new List<ItemStatLine>(1) { new ItemStatLine("Bonus Health: ", (ValueType)2, (MeasurementUnits)2) }, delegate(CharacterMaster master, int itemCount) { float num2 = Utilities.GetLinearStacking(WarmogsArmor.flatHealth, WarmogsArmor.flatHealthExtraStacks, itemCount); CharacterBody body2 = master.GetBody(); if (Object.op_Implicit((Object)(object)((body2 != null) ? body2.healthComponent : null))) { num2 += master.GetBody().healthComponent.fullHealth * WarmogsArmor.percentHealthBonus; } return new List<float>(1) { num2 }; }); RegisterStatsForItem(WarmogsArmor.radiantDef, new List<ItemStatLine>(1) { new ItemStatLine("Bonus Health: ", (ValueType)2, (MeasurementUnits)2) }, delegate(CharacterMaster master, int itemCount) { float num = Utilities.GetLinearStacking(WarmogsArmor.flatHealth, WarmogsArmor.flatHealthExtraStacks, itemCount) * PercentRadiantItemStatMultiplier; CharacterBody body = master.GetBody(); if (Object.op_Implicit((Object)(object)((body != null) ? body.healthComponent : null))) { num += master.GetBody().healthComponent.fullHealth * WarmogsArmor.percentHealthBonus * PercentRadiantItemStatMultiplier; } return new List<float>(1) { num }; }); } if (GamblersBlade.isEnabled.Value) { RegisterStatsForItem(GamblersBlade.itemDef, new List<ItemStatLine>(1) { new ItemStatLine("Max Money Threshold: ", (ValueType)16, (MeasurementUnits)5) }, (CharacterMaster master, int itemCount) => new List<float>(1) { (float)GamblersBlade.moneyEffectCap.Value * Utilities.GetDifficultyAsMultiplier() }); } if (HorizonFocus.isEnabled.Value) { RegisterStatsForItem(HorizonFocus.itemDef, new List<ItemStatLine>(2) { new ItemStatLine("Stun Chance: ", (ValueType)2, (MeasurementUnits)1), new ItemStatLine("Explosion Damage: ", (ValueType)3, (MeasurementUnits)7) }, delegate(CharacterMaster master, int itemCount) { List<float> list = new List<float>(); if (Object.op_Implicit((Object)(object)master)) { list.Add(Utilities.GetChanceAfterLuck(HorizonFocus.percentStunChance, master.luck)); } else { list.Add(HorizonFocus.percentStunChance); } list.Add(Utilities.GetHyperbolicStacking(HorizonFocus.percentLightningDamage, HorizonFocus.percentLightningDamageExtraStacks, itemCount)); return list; }); } if (LightshieldCrest.isEnabled.Value) { RegisterStatsForItem(LightshieldCrest.itemDef, new List<ItemStatLine>(1) { new ItemStatLine("Armor Conversion: ", (ValueType)17, (MeasurementUnits)1) }, (CharacterMaster master, int itemCount) => new List<float>(1) { Utilities.GetLinearStacking(LightshieldCrest.percentArmor, LightshieldCrest.percentArmorExtraStacks, itemCount) }); } if (Mittens.isEnabled.Value) { RegisterStatsForItem(Mittens.itemDef, new List<ItemStatLine>(2) { new ItemStatLine("Attack Speed: ", (ValueType)1, (MeasurementUnits)1), new ItemStatLine("Movement Speed: ", (ValueType)2, (MeasurementUnits)1) }, (CharacterMaster master, int itemCount) => new List<float>(2) { Utilities.GetLinearStacking(Mittens.percentAttackSpeed, Mittens.percentAttackSpeedExtraStacks, itemCount), Utilities.GetLinearStacking(Mittens.percentMovementSpeed, Mittens.percentMovementSpeedExtraStacks, itemCount) }); } if (SnipersFocus.isEnabled.Value) { RegisterStatsForItem(SnipersFocus.itemDef, new List<ItemStatLine>(1) { new ItemStatLine("Damage Per Meter: ", (ValueType)1, (MeasurementUnits)1) }, (CharacterMaster master, int itemCount) => new List<float>(1) { Utilities.GetLinearStacking(SnipersFocus.percentDamageIncreasePerMeter, SnipersFocus.percentDamageIncreasePerMeterExtraStacks, itemCount) }); } } private static void RegisterStatsForItemWithRadiantVariant(ItemDef defaultItem, ItemDef radiantItem, List<ItemStatLine> statLines, Func<CharacterMaster, int, List<float>> func) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected I4, but got Unknown ItemDef[] array = (ItemDef[])(object)new ItemDef[2] { defaultItem, radiantItem }; foreach (ItemDef val in array) { if (!Object.op_Implicit((Object)(object)val)) { throw new ArgumentNullException("itemDef"); } ItemStatsDef val2 = new ItemStatsDef(); foreach (ItemStatLine statLine in statLines) { val2.descriptions.Add(statLine.Name); val2.valueTypes.Add(statLine.ValueType); val2.measurementUnits.Add(statLine.Units); } val2.calculateValues = func; ItemDefinitions.allItemDefinitions.Add((int)val.itemIndex, val2); } } private static void RegisterStatsForItem(ItemDef itemDef, List<ItemStatLine> statLines, Func<CharacterMaster, int, List<float>> func) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected I4, but got Unknown if (!Object.op_Implicit((Object)(object)itemDef)) { throw new ArgumentNullException("itemDef"); } ItemStatsDef val = new ItemStatsDef(); foreach (ItemStatLine statLine in statLines) { val.descriptions.Add(statLine.Name); val.valueTypes.Add(statLine.ValueType); val.measurementUnits.Add(statLine.Units); } val.calculateValues = func; ItemDefinitions.allItemDefinitions.Add((int)itemDef.itemIndex, val); } } private static float PercentRadiantItemStatMultiplier => ConfigManager.Scaling.radiantItemStatMultiplier; internal static void Init() { RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(LookingGlassStats.RegisterStats)); } } } namespace RiskOfTactics.Content.Items.Completes { public class AdaptiveHelmItemBehavior : BaseItemBodyBehavior { [ItemDefAssociation(useOnServer = true, useOnClient = false)] public static ItemDef GetItemDef() { return AdaptiveHelm.itemDef; } public void FixedUpdate() { AdaptiveHelm.FixedUpdateHook(((BaseItemBodyBehavior)this).body, base.stack, AdaptiveHelm.cooldownResetBuff); } } public class RadiantAdaptiveHelmItemBehavior : BaseItemBodyBehavior { [ItemDefAssociation(useOnServer = true, useOnClient = false)] public static ItemDef GetItemDef() { return AdaptiveHelm.radiantDef; } public void FixedUpdate() { AdaptiveHelm.FixedUpdateHook(((BaseItemBodyBehavior)this).body, base.stack, AdaptiveHelm.radiantCooldownResetBuff); } } internal class AdaptiveHelm { public static ItemDef itemDef; public static BuffDef cooldownResetBuff; public static ItemDef radiantDef; public static BuffDef radiantCooldownResetBuff; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Adaptive Helm", "Enabled", defaultValue: true, "Whether or not the item is enabled.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }); public static ConfigurableValue<float> commonStatBoost = new ConfigurableValue<float>("Item: Adaptive Helm", "Common Stat Boost", 20f, "Base armor and % max HP shield for all users.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> meleeResistBonus = new ConfigurableValue<float>("Item: Adaptive Helm", "Melee: Bonus Resist", 20f, "Melee: Armor and % shield bonus for melee users for the first stack.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> meleeResistBonusExtraStacks = new ConfigurableValue<float>("Item: Adaptive Helm", "Melee: Bonus Resist Extra Stacks", 20f, "Melee: Armor and % shield bonus for melee users with extra stacks.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> cooldownRefundOnTakeDamage = new ConfigurableValue<float>("Item: Adaptive Helm", "Melee: Cooldown Refund", 0.5f, "Melee: Seconds cooldown refunded when taking damage.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> rangedDamageBonus = new ConfigurableValue<float>("Item: Adaptive Helm", "Ranged: Bonus Damage", 1f, "Ranged: Flat damage bonus for ranged users for the first stack.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> rangedDamageBonusExtraStacks = new ConfigurableValue<float>("Item: Adaptive Helm", "Ranged: Bonus Damage Extra Stacks", 1f, "Ranged: Flat damage bonus for ranged users with extra stacks.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> cooldownRefreshInterval = new ConfigurableValue<float>("Item: Adaptive Helm", "Ranged: Cooldown Interval", 20f, "Ranged: All cooldowns are refunded on this interval for ranged item users.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }); public static ConfigurableValue<float> cooldownRefreshIntervalReduction = new ConfigurableValue<float>("Item: Adaptive Helm", "Ranged: Cooldown Interval Reduction", 20f, "Ranged: Cooldown refund timer for this item is reduced by this percentage per stack for ranged users.", new List<string>(1) { "ITEM_ROT_ADAPTIVEHELM_DESC" }); public static readonly float percentCommonStatBoost = commonStatBoost.Value / 100f; public static readonly float percentMeleeResistBonus = meleeResistBonus.Value / 100f; public static readonly float percentMeleeResistBonusExtraStacks = meleeResistBonusExtraStacks.Value / 100f; public static readonly float percentCooldownRefreshIntervalReduction = cooldownRefreshIntervalReduction.Value / 100f; internal static void Init() { ItemTag[] array = new ItemTag[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); itemDef = ItemManager.GenerateItem("AdaptiveHelm", (ItemTag[])(object)array, ItemManager.TacticTier.Normal); ItemTag[] array2 = new ItemTag[3]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); radiantDef = ItemManager.GenerateItem("Radiant_AdaptiveHelm", (ItemTag[])(object)array2, ItemManager.TacticTier.Radiant); cooldownResetBuff = Utilities.GenerateBuffDef("CooldownResetBuff", AssetManager.bundle.LoadAsset<Sprite>("AdaptiveHelm"), canStack: false, isHidden: false, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(cooldownResetBuff); radiantCooldownResetBuff = Utilities.GenerateBuffDef("RadiantCooldownResetBuff", AssetManager.bundle.LoadAsset<Sprite>("Radiant_AdaptiveHelm"), canStack: false, isHidden: false, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(radiantCooldownResetBuff); Utilities.RegisterRadiantUpgrade(itemDef, radiantDef); Hooks(itemDef, ItemManager.TacticTier.Normal, cooldownResetBuff); Hooks(radiantDef, ItemManager.TacticTier.Radiant, radiantCooldownResetBuff); } public static void Hooks(ItemDef def, ItemManager.TacticTier tier, BuffDef cooldownReset) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown float radiantMultiplier = (tier.Equals(ItemManager.TacticTier.Radiant) ? ((float)ConfigManager.Scaling.radiantItemStatMultiplier) : 1f); RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)delegate(CharacterBody sender, StatHookEventArgs args) { if (Object.op_Implicit((Object)(object)sender) && Object.op_Implicit((Object)(object)sender.inventory)) { int itemCountEffective2 = sender.inventory.GetItemCountEffective(def); if (itemCountEffective2 > 0) { args.armorAdd += Utilities.GetLinearStacking(commonStatBoost.Value * radiantMultiplier, 0f, itemCountEffective2); args.baseShieldAdd += sender.healthComponent.fullHealth * Utilities.GetLinearStacking(percentCommonStatBoost * radiantMultiplier, 0f, itemCountEffective2); if (Utilities.IsMeleeBodyPrefab(((Component)sender).gameObject)) { args.armorTotalMult *= 1f + Utilities.GetLinearStacking(percentMeleeResistBonus * radiantMultiplier, percentMeleeResistBonusExtraStacks * radiantMultiplier, itemCountEffective2); args.shieldTotalMult *= 1f + Utilities.GetLinearStacking(percentMeleeResistBonus * radiantMultiplier, percentMeleeResistBonusExtraStacks * radiantMultiplier, itemCountEffective2); } if (Utilities.IsRangedBodyPrefab(((Component)sender).gameObject)) { args.baseDamageAdd += Utilities.GetLinearStacking(rangedDamageBonus.Value * radiantMultiplier, rangedDamageBonusExtraStacks.Value * radiantMultiplier, itemCountEffective2); } } } }; CharacterBody.OnBuffFinalStackLost += (hook_OnBuffFinalStackLost)delegate(orig_OnBuffFinalStackLost orig, CharacterBody self, BuffDef buffDef) { orig.Invoke(self, buffDef); if (Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.skillLocator) && (Object)(object)buffDef == (Object)(object)cooldownReset) { self.skillLocator.ResetSkills(); } }; GameEventManager.OnTakeDamage += delegate(DamageReport damageReport) { CharacterBody victimBody = damageReport.victimBody; if (Object.op_Implicit((Object)(object)victimBody) && Object.op_Implicit((Object)(object)victimBody.inventory) && Object.op_Implicit((Object)(object)victimBody.skillLocator)) { int itemCountEffective = victimBody.inventory.GetItemCountEffective(def); if (itemCountEffective > 0 && Utilities.IsMeleeBodyPrefab(((Component)victimBody).gameObject)) { victimBody.skillLocator.DeductCooldownFromAllSkillsServer(cooldownRefundOnTakeDamage.Value * radiantMultiplier); } } }; } internal static void FixedUpdateHook(CharacterBody self, int itemCount, BuffDef cooldownReset) { if (Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.inventory) && itemCount > 0 && Utilities.IsRangedBodyPrefab(((Component)self).gameObject) && !self.HasBuff(cooldownReset)) { self.AddTimedBuff(cooldownReset, Utilities.GetReverseExponentialStacking(cooldownRefreshInterval.Value, percentCooldownRefreshIntervalReduction, itemCount)); } } } public class ArchangelsStaffItemBehavior : BaseItemBodyBehavior { [ItemDefAssociation(useOnServer = true, useOnClient = false)] public static ItemDef GetItemDef() { return ArchangelsStaff.itemDef; } public void FixedUpdate() { ArchangelsStaff.FixedUpdateHook(((BaseItemBodyBehavior)this).body, base.stack, ArchangelsStaff.staffIntervalCooldown); } } public class ArchangelsStaffRadiantItemBehavior : BaseItemBodyBehavior { [ItemDefAssociation(useOnServer = true, useOnClient = false)] public static ItemDef GetItemDef() { return ArchangelsStaff.radiantDef; } public void FixedUpdate() { ArchangelsStaff.FixedUpdateHook(((BaseItemBodyBehavior)this).body, base.stack, ArchangelsStaff.staffRadiantIntervalCooldown); } } internal class ArchangelsStaff { public static BuffDef foresightBuff; public static ItemDef itemDef; public static BuffDef staffIntervalCooldown; public static ItemDef radiantDef; public static BuffDef staffRadiantIntervalCooldown; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Archangels Staff", "Enabled", defaultValue: true, "Whether or not the item is enabled.", new List<string>(1) { "ITEM_ROT_ARCHANGELSSTAFF_DESC" }); public static ConfigurableValue<float> flatDamagePerTick = new ConfigurableValue<float>("Item: Archangels Staff", "Flat Damage Per Tick", 0.5f, "Flat damage gained per item proc.", new List<string>(1) { "ITEM_ROT_ARCHANGELSSTAFF_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> tickDuration = new ConfigurableValue<float>("Item: Archangels Staff", "Tick Duration", 5f, "Number of seconds between item procs.", new List<string>(1) { "ITEM_ROT_ARCHANGELSSTAFF_DESC" }); internal static void Init() { itemDef = ItemManager.GenerateItem("ArchangelsStaff", (ItemTag[])(object)new ItemTag[2] { (ItemTag)1, (ItemTag)31 }, ItemManager.TacticTier.Normal); radiantDef = ItemManager.GenerateItem("Radiant_ArchangelsStaff", (ItemTag[])(object)new ItemTag[2] { (ItemTag)1, (ItemTag)31 }, ItemManager.TacticTier.Radiant); foresightBuff = Utilities.GenerateBuffDef("Foresight", AssetManager.bundle.LoadAsset<Sprite>("Foresight.png"), canStack: true, isHidden: false, isDebuff: false, isCooldown: false); ContentAddition.AddBuffDef(foresightBuff); staffIntervalCooldown = Utilities.GenerateBuffDef("ArchangelIntervalCooldown", AssetManager.bundle.LoadAsset<Sprite>("ArchangelsStaff.png"), canStack: false, isHidden: true, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(staffIntervalCooldown); staffRadiantIntervalCooldown = Utilities.GenerateBuffDef("RadiantArchangelIntervalCooldown", AssetManager.bundle.LoadAsset<Sprite>("Radiant_ArchangelsStaff.png"), canStack: false, isHidden: true, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(staffRadiantIntervalCooldown); Utilities.RegisterRadiantUpgrade(itemDef, radiantDef); Hooks(itemDef, staffIntervalCooldown, ItemManager.TacticTier.Normal); Hooks(radiantDef, staffRadiantIntervalCooldown, ItemManager.TacticTier.Radiant); } public static void Hooks(ItemDef def, BuffDef cooldownBuff, ItemManager.TacticTier tier) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown float radiantMultiplier = (tier.Equals(ItemManager.TacticTier.Radiant) ? ((float)ConfigManager.Scaling.radiantItemStatMultiplier) : 1f); RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)delegate(CharacterBody sender, StatHookEventArgs args) { if (Object.op_Implicit((Object)(object)sender)) { int buffCount = sender.GetBuffCount(foresightBuff); args.baseDamageAdd += (float)buffCount * flatDamagePerTick.Value * radiantMultiplier; } }; HoldoutZoneController.Start += (hook_Start)delegate(orig_Start orig, HoldoutZoneController self) { orig.Invoke(self); foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { CharacterMaster val = readOnlyInstances.masterController.master ?? readOnlyInstances.master; if (Object.op_Implicit((Object)(object)val)) { CharacterBody body = val.GetBody(); if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory) && body.inventory.GetItemCountEffective(def) > 0) { body.AddTimedBuff(cooldownBuff, tickDuration.Value); } } } }; CharacterBody.OnBuffFinalStackLost += (hook_OnBuffFinalStackLost)delegate(orig_OnBuffFinalStackLost orig, CharacterBody self, BuffDef buffDef) { orig.Invoke(self, buffDef); if ((Object)(object)buffDef == (Object)(object)cooldownBuff && Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.inventory)) { int itemCountEffective = self.inventory.GetItemCountEffective(def); if (itemCountEffective > 0 && InstanceTracker.GetInstancesList<HoldoutZoneController>().Count > 0) { self.AddBuff(foresightBuff); self.AddTimedBuff(cooldownBuff, tickDuration.Value); } } }; } public static void FixedUpdateHook(CharacterBody body, int itemCount, BuffDef cooldownBuff) { foreach (HoldoutZoneController instances in InstanceTracker.GetInstancesList<HoldoutZoneController>()) { if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory) && itemCount > 0 && ((Behaviour)instances).isActiveAndEnabled && !body.HasBuff(cooldownBuff)) { body.AddTimedBuff(cooldownBuff, tickDuration.Value); } } } } internal class Bloodthirster { public static ItemDef itemDef; public static BuffDef satedBuff; public static ItemDef radiantDef; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Bloodthirster", "Enabled", defaultValue: true, "Whether or not the item is enabled.", new List<string>(1) { "ITEM_ROT_BLOODTHIRSTER_DESC" }); public static ConfigurableValue<float> effectCooldown = new ConfigurableValue<float>("Item: Bloodthirster", "Effect Cooldown", 60f, "Cooldown of this item's effect.", new List<string>(1) { "ITEM_ROT_BLOODTHIRSTER_DESC" }); public static ConfigurableValue<float> barrierTriggerHP = new ConfigurableValue<float>("Item: Bloodthirster", "HP Threshold", 25f, "Threshold needed to fall below in order to trigger this item's effect.", new List<string>(1) { "ITEM_ROT_BLOODTHIRSTER_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> barrierSize = new ConfigurableValue<float>("Item: Bloodthirster", "Percent Barrier", 20f, "Percent max HP barrier given when this item is procced.", new List<string>(1) { "ITEM_ROT_BLOODTHIRSTER_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> barrierSizeExtraStacks = new ConfigurableValue<float>("Item: Bloodthirster", "Percent Barrier Extra Stacks", 20f, "Percent max HP barrier given when extra stacks of item are procced.", new List<string>(1) { "ITEM_ROT_BLOODTHIRSTER_DESC" }, isRadiantStat: true); private static readonly float percentBarrierTriggerHP = barrierTriggerHP.Value / 100f; private static readonly float percentBarrierSize = barrierSize.Value / 100f; private static readonly float percentBarrierSizeExtraStacks = barrierSizeExtraStacks.Value / 100f; internal static void Init() { ItemTag[] array = new ItemTag[4]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); itemDef = ItemManager.GenerateItem("Bloodthirster", (ItemTag[])(object)array, ItemManager.TacticTier.Normal); ItemTag[] array2 = new ItemTag[4]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); radiantDef = ItemManager.GenerateItem("Radiant_Bloodthirster", (ItemTag[])(object)array2, ItemManager.TacticTier.Radiant); satedBuff = Utilities.GenerateBuffDef("Sated", AssetManager.bundle.LoadAsset<Sprite>("Sated.png"), canStack: false, isHidden: false, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(satedBuff); Utilities.RegisterRadiantUpgrade(itemDef, radiantDef); Hooks(itemDef, ItemManager.TacticTier.Normal); Hooks(radiantDef, ItemManager.TacticTier.Radiant); } public static void Hooks(ItemDef def, ItemManager.TacticTier tier) { float radiantMultiplier = (tier.Equals(ItemManager.TacticTier.Radiant) ? ((float)ConfigManager.Scaling.radiantItemStatMultiplier) : 1f); GameEventManager.OnTakeDamage += delegate(DamageReport damageReport) { CharacterBody victimBody = damageReport.victimBody; if (Object.op_Implicit((Object)(object)victimBody) && Object.op_Implicit((Object)(object)victimBody.inventory) && Object.op_Implicit((Object)(object)victimBody.healthComponent)) { int itemCountEffective = victimBody.inventory.GetItemCountEffective(def); if (itemCountEffective > 0 && !victimBody.HasBuff(satedBuff) && victimBody.healthComponent.combinedHealthFraction < percentBarrierTriggerHP * radiantMultiplier) { victimBody.healthComponent.AddBarrier(victimBody.healthComponent.fullCombinedHealth * Utilities.GetLinearStacking(percentBarrierSize * radiantMultiplier, percentBarrierSizeExtraStacks * radiantMultiplier, itemCountEffective)); victimBody.AddTimedBuff(satedBuff, effectCooldown.Value); } } }; } } public class BrambleVest { public class Statistics : MonoBehaviour { public class Sync : INetMessage, ISerializableObject { private NetworkInstanceId objId; private float damageReflected; public Sync() { } public Sync(NetworkInstanceId objId, float damage) { //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) this.objId = objId; damageReflected = damage; } public void Deserialize(NetworkReader reader) { //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) objId = reader.ReadNetworkId(); damageReflected = reader.ReadSingle(); } public void OnReceived() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } GameObject val = Util.FindNetworkObject(objId); if ((Object)(object)val != (Object)null) { Statistics component = val.GetComponent<Statistics>(); if ((Object)(object)component != (Object)null) { component.DamageReflected = damageReflected; } } } public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) writer.Write(objId); writer.Write(damageReflected); writer.FinishMessage(); } } private float _damageReflected; public float DamageReflected { get { return _damageReflected; } set { //IL_001d: Unknown result type (might be due to invalid IL or missing references) _damageReflected = value; if (NetworkServer.active) { NetMessageExtensions.Send((INetMessage)(object)new Sync(((Component)this).gameObject.GetComponent<NetworkIdentity>().netId, value), (NetworkDestination)1); } } } } public class BrambleOrb : Orb { private readonly float speed = 60f; private readonly float multi; private readonly DamageReport damageReport; public BrambleOrb(DamageReport report, float radiantMult) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) damageReport = report; multi = radiantMult; if (Object.op_Implicit((Object)(object)report.victimBody) && Object.op_Implicit((Object)(object)report.attackerBody)) { base.origin = (Object.op_Implicit((Object)(object)report.victimBody) ? report.victimBody.corePosition : Vector3.zero); if (Object.op_Implicit((Object)(object)report.attackerBody)) { base.target = report.attackerBody.mainHurtBox; } } } public override void Begin() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown ((Orb)this).duration = ((Orb)this).distanceToTarget / speed; EffectData val = new EffectData { origin = base.origin, genericFloat = ((Orb)this).duration }; val.SetHurtBoxReference(base.target); EffectManager.SpawnEffect(OrbStorageUtility.Get("Prefabs/Effects/OrbEffects/ClayGooOrbEffect"), val, true); } public override void OnArrival() { //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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)damageReport.attackerBody) && Object.op_Implicit((Object)(object)damageReport.victimBody) && Object.op_Implicit((Object)(object)damageReport.victimBody.inventory)) { CharacterBody victimBody = damageReport.victimBody; CharacterBody attackerBody = damageReport.attackerBody; int itemCountEffective = damageReport.victimBody.inventory.GetItemCountEffective(itemDef); DamageInfo val = new DamageInfo { damage = damageReport.damageInfo.damage * Utilities.GetLinearStacking(percentReflectDamage * multi, itemCountEffective), damageColorIndex = (DamageColorIndex)4, damageType = DamageTypeCombo.op_Implicit((DamageType)0), attacker = ((Component)victimBody).gameObject, crit = victimBody.RollCrit(), inflictor = ((Component)victimBody).gameObject, procCoefficient = reflectProcCoefficient, procChainMask = default(ProcChainMask) }; attackerBody.healthComponent.TakeDamage(val); CharacterBody minionOwnershipParentBody = Utilities.GetMinionOwnershipParentBody(damageReport.victimBody); Statistics component = ((Component)minionOwnershipParentBody.inventory).GetComponent<Statistics>(); if (Object.op_Implicit((Object)(object)component)) { component.DamageReflected += val.damage; } } } } public static ItemDef itemDef; public static ItemDef radiantDef; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Bramble Vest", "Enabled", defaultValue: true, "Whether or not the item is enabled.", new List<string>(1) { "ITEM_ROT_BRAMBLEVEST_DESC" }); public static ConfigurableValue<float> healthBonus = new ConfigurableValue<float>("Item: Bramble Vest", "Health", 5f, "Percent health bonus when holding this item.", new List<string>(1) { "ITEM_ROT_BRAMBLEVEST_DESC" }, isRadiantStat: true); public static ConfigurableValue<int> flatDamageReduction = new ConfigurableValue<int>("Item: Bramble Vest", "Damage Reduction", 5, "Flat damage reduction bonus when holding this item.", new List<string>(1) { "ITEM_ROT_BRAMBLEVEST_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> reflectDamage = new ConfigurableValue<float>("Item: Bramble Vest", "Reflect Percent", 100f, "Percent damage reflected back to the attacker when holding this item.", new List<string>(1) { "ITEM_ROT_BRAMBLEVEST_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> reflectProcCoefficient = new ConfigurableValue<float>("Item: Bramble Vest", "Reflect Proc Coefficient", 0.5f, "Proc coefficient for the reflected damage hit when holding this item.", new List<string>(1) { "ITEM_ROT_BRAMBLEVEST_DESC" }); public static readonly float percentHealthBonus = healthBonus.Value / 100f; public static readonly float percentReflectDamage = reflectDamage.Value / 100f; internal static void Init() { ItemTag[] array = new ItemTag[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); itemDef = ItemManager.GenerateItem("BrambleVest", (ItemTag[])(object)array, ItemManager.TacticTier.Normal); ItemTag[] array2 = new ItemTag[3]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); radiantDef = ItemManager.GenerateItem("Radiant_BrambleVest", (ItemTag[])(object)array2, ItemManager.TacticTier.Radiant); NetworkingAPI.RegisterMessageType<Statistics.Sync>(); Utilities.RegisterRadiantUpgrade(itemDef, radiantDef); Hooks(itemDef, ItemManager.TacticTier.Normal); Hooks(radiantDef, ItemManager.TacticTier.Radiant); } public static void Hooks(ItemDef def, ItemManager.TacticTier tier) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown float radiantMultiplier = (tier.Equals(ItemManager.TacticTier.Radiant) ? ((float)ConfigManager.Scaling.radiantItemStatMultiplier) : 1f); CharacterMaster.onStartGlobal += delegate(CharacterMaster obj) { Inventory inventory = obj.inventory; if (inventory != null) { ((Component)inventory).gameObject.AddComponent<Statistics>(); } }; RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)delegate(CharacterBody sender, StatHookEventArgs args) { if (Object.op_Implicit((Object)(object)sender) && Object.op_Implicit((Object)(object)sender.inventory)) { int itemCountEffective3 = sender.inventory.GetItemCountEffective(def); if (itemCountEffective3 > 0) { args.healthTotalMult *= 1f + percentHealthBonus * radiantMultiplier; } } }; GameEventManager.BeforeTakeDamage += delegate(DamageInfo damageInfo, GameEventManager.GenericCharacterInfo attackerInfo, GameEventManager.GenericCharacterInfo victimInfo) { CharacterBody body = victimInfo.body; if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory)) { int itemCountEffective2 = body.inventory.GetItemCountEffective(def); if (itemCountEffective2 > 0) { damageInfo.damage = ((damageInfo.damage > (float)flatDamageReduction.Value * radiantMultiplier + 1f) ? (damageInfo.damage - (float)flatDamageReduction.Value * radiantMultiplier) : 1f); } } }; GameEventManager.OnTakeDamage += delegate(DamageReport damageReport) { CharacterBody victimBody = damageReport.victimBody; CharacterBody attackerBody = damageReport.attackerBody; if (Object.op_Implicit((Object)(object)victimBody) && Object.op_Implicit((Object)(object)victimBody.inventory) && Object.op_Implicit((Object)(object)attackerBody) && Object.op_Implicit((Object)(object)attackerBody.healthComponent)) { int itemCountEffective = victimBody.inventory.GetItemCountEffective(def); if (itemCountEffective > 0 && !Utilities.OnSameTeam(victimBody, attackerBody)) { OrbManager.instance.AddOrb((Orb)(object)new BrambleOrb(damageReport, radiantMultiplier)); } } }; } } internal class Crownguard { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_OnBuffFinalStackLost <>9__13_1; internal void <Hooks>b__13_1(orig_OnBuffFinalStackLost orig, CharacterBody self, BuffDef buffDef) { orig.Invoke(self, buffDef); if (Object.op_Implicit((Object)(object)self) && (Object)(object)buffDef == (Object)(object)guardedBuff) { self.AddBuff(crownedBuff); } } } public static ItemDef itemDef; public static BuffDef guardedBuff; public static BuffDef crownedBuff; public static ItemDef radiantDef; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Crownguard", "Enabled", defaultValue: true, "Whether or not the item is enabled.", new List<string>(1) { "ITEM_ROT_CROWNGUARD_DESC" }); public static ConfigurableValue<float> effectShield = new ConfigurableValue<float>("Item: Crownguard", "Effect Shield", 25f, "Percent max HP shield bonus when teleporter is activated.", new List<string>(1) { "ITEM_ROT_CROWNGUARD_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> effectShieldExtraStacks = new ConfigurableValue<float>("Item: Crownguard", "Effect Shield Extra Stacks", 25f, "Percent max HP shield bonus with extra stacks when teleporter is activated.", new List<string>(1) { "ITEM_ROT_CROWNGUARD_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> effectDuration = new ConfigurableValue<float>("Item: Crownguard", "Effect Duration", 30f, "How long the shield effect lasts when teleporter is activated.", new List<string>(1) { "ITEM_ROT_CROWNGUARD_DESC" }); public static ConfigurableValue<float> effectDamage = new ConfigurableValue<float>("Item: Crownguard", "Effect Damage", 2.5f, "Damage bonus given after the shield effect expires.", new List<string>(1) { "ITEM_ROT_CROWNGUARD_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> effectDamageExtraStacks = new ConfigurableValue<float>("Item: Crownguard", "Effect Damage Extra Stacks", 2f, "Damage bonus given after the shield effect expires.", new List<string>(1) { "ITEM_ROT_CROWNGUARD_DESC" }, isRadiantStat: true); private static readonly float percentEffectShield = effectShield.Value / 100f; private static readonly float percentEffectShieldExtraStacks = effectShieldExtraStacks.Value / 100f; internal static void Init() { ItemTag[] array = new ItemTag[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); itemDef = ItemManager.GenerateItem("Crownguard", (ItemTag[])(object)array, ItemManager.TacticTier.Normal); ItemTag[] array2 = new ItemTag[3]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); radiantDef = ItemManager.GenerateItem("Radiant_Crownguard", (ItemTag[])(object)array2, ItemManager.TacticTier.Radiant); guardedBuff = Utilities.GenerateBuffDef("Guarded", AssetManager.bundle.LoadAsset<Sprite>("Guarded.png"), canStack: false, isHidden: false, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(guardedBuff); crownedBuff = Utilities.GenerateBuffDef("Crowned", AssetManager.bundle.LoadAsset<Sprite>("Crowned.png"), canStack: false, isHidden: false, isDebuff: false, isCooldown: false); ContentAddition.AddBuffDef(crownedBuff); Utilities.RegisterRadiantUpgrade(itemDef, radiantDef); Hooks(itemDef, ItemManager.TacticTier.Normal); Hooks(radiantDef, ItemManager.TacticTier.Radiant); } public static void Hooks(ItemDef def, ItemManager.TacticTier tier) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown float radiantMultiplier = (tier.Equals(ItemManager.TacticTier.Radiant) ? ((float)ConfigManager.Scaling.radiantItemStatMultiplier) : 1f); RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)delegate(CharacterBody sender, StatHookEventArgs args) { if (Object.op_Implicit((Object)(object)sender) && Object.op_Implicit((Object)(object)sender.inventory)) { int itemCountEffective = sender.inventory.GetItemCountEffective(def); if (itemCountEffective > 0) { if (sender.GetBuffCount(guardedBuff) > 0) { args.baseShieldAdd += sender.healthComponent.fullHealth * Utilities.GetLinearStacking(percentEffectShield * radiantMultiplier, percentEffectShieldExtraStacks * radiantMultiplier, itemCountEffective); } if (sender.GetBuffCount(crownedBuff) > 0) { args.baseDamageAdd += Utilities.GetLinearStacking(effectDamage.Value * radiantMultiplier, effectDamageExtraStacks.Value * radiantMultiplier, itemCountEffective); } } } }; object obj = <>c.<>9__13_1; if (obj == null) { hook_OnBuffFinalStackLost val = delegate(orig_OnBuffFinalStackLost orig, CharacterBody self, BuffDef buffDef) { orig.Invoke(self, buffDef); if (Object.op_Implicit((Object)(object)self) && (Object)(object)buffDef == (Object)(object)guardedBuff) { self.AddBuff(crownedBuff); } }; <>c.<>9__13_1 = val; obj = (object)val; } CharacterBody.OnBuffFinalStackLost += (hook_OnBuffFinalStackLost)obj; HoldoutZoneController.Start += (hook_Start)delegate(orig_Start orig, HoldoutZoneController self) { orig.Invoke(self); foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { CharacterMaster val2 = readOnlyInstances.masterController.master ?? readOnlyInstances.master; if (Object.op_Implicit((Object)(object)val2)) { CharacterBody body = val2.GetBody(); if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inventory) && body.inventory.GetItemCountEffective(def) > 0) { body.AddTimedBuff(guardedBuff, effectDuration.Value * radiantMultiplier); } } } }; } } public class DragonsClawItemBehavior : BaseItemBodyBehavior { [ItemDefAssociation(useOnServer = true, useOnClient = false)] public static ItemDef GetItemDef() { return DragonsClaw.itemDef; } public void FixedUpdate() { DragonsClaw.FixedUpdateHook(((BaseItemBodyBehavior)this).body, base.stack, DragonsClaw.dragonsClawCooldownBuff); } } public class RadiantDragonsClawItemBehavior : BaseItemBodyBehavior { [ItemDefAssociation(useOnServer = true, useOnClient = false)] public static ItemDef GetItemDef() { return DragonsClaw.radiantDef; } public void FixedUpdate() { DragonsClaw.FixedUpdateHook(((BaseItemBodyBehavior)this).body, base.stack, DragonsClaw.radiantDragonsClawCooldownBuff); } } internal class DragonsClaw { public static ItemDef itemDef; public static BuffDef dragonsClawCooldownBuff; public static ItemDef radiantDef; public static BuffDef radiantDragonsClawCooldownBuff; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Dragons Claw", "Enabled", defaultValue: true, "Whether or not the item is enabled.", new List<string>(1) { "ITEM_ROT_DRAGONSCLAW_DESC" }); public static ConfigurableValue<float> maxHealthBonus = new ConfigurableValue<float>("Item: Dragons Claw", "Percent Health", 8f, "Percent max health bonus when holding this item.", new List<string>(1) { "ITEM_ROT_DRAGONSCLAW_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> maxHealthBonusExtraStacks = new ConfigurableValue<float>("Item: Dragons Claw", "Percent Health Per Stack", 8f, "Percent max health bonus when holding extra stacks of this item.", new List<string>(1) { "ITEM_ROT_DRAGONSCLAW_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> healingPerTick = new ConfigurableValue<float>("Item: Dragons Claw", "Healing Per Tick", 4f, "Percent max health healing per item proc.", new List<string>(1) { "ITEM_ROT_DRAGONSCLAW_DESC" }, isRadiantStat: true); public static ConfigurableValue<float> tickDuration = new ConfigurableValue<float>("Item: Dragons Claw", "Tick Duration", 8f, "Number of seconds between item procs.", new List<string>(1) { "ITEM_ROT_DRAGONSCLAW_DESC" }); public static readonly float percentHealingPerTick = healingPerTick.Value / 100f; public static readonly float percentMaxHealthBonus = maxHealthBonus.Value / 100f; public static readonly float percentMaxHealthBonusExtraStacks = maxHealthBonusExtraStacks.Value / 100f; internal static void Init() { ItemTag[] array = new ItemTag[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); itemDef = ItemManager.GenerateItem("DragonsClaw", (ItemTag[])(object)array, ItemManager.TacticTier.Normal); dragonsClawCooldownBuff = Utilities.GenerateBuffDef("DragonsClawCooldown", AssetManager.bundle.LoadAsset<Sprite>("DragonsClawCooldown"), canStack: false, isHidden: false, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(dragonsClawCooldownBuff); ItemTag[] array2 = new ItemTag[3]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); radiantDef = ItemManager.GenerateItem("Radiant_DragonsClaw", (ItemTag[])(object)array2, ItemManager.TacticTier.Radiant); radiantDragonsClawCooldownBuff = Utilities.GenerateBuffDef("DragonsClawRadiantCooldown", AssetManager.bundle.LoadAsset<Sprite>("DragonsClawRadiantCooldown"), canStack: false, isHidden: false, isDebuff: false, isCooldown: true); ContentAddition.AddBuffDef(radiantDragonsClawCooldownBuff); Utilities.RegisterRadiantUpgrade(itemDef, radiantDef); Hooks(itemDef, dragonsClawCooldownBuff, ItemManager.TacticTier.Normal); Hooks(radiantDef, radiantDragonsClawCooldownBuff, ItemManager.TacticTier.Radiant); } public static void Hooks(ItemDef def, BuffDef cooldownBuff, ItemManager.TacticTier tier) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown float radiantMultiplier = (tier.Equals(ItemManager.TacticTier.Radiant) ? ((float)ConfigManager.Scaling.radiantItemStatMultiplier) : 1f); RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)delegate(CharacterBody sender, StatHookEventArgs args) { if (Object.op_Implicit((Object)(object)sender) && Object.op_Implicit((Object)(object)sender.inventory)) { int itemCountEffective = sender.inventory.GetItemCountEffective(def); if (itemCountEffective > 0) { args.healthTotalMult *= 1f + Utilities.GetLinearStacking(percentMaxHealthBonus * radiantMultiplier, percentMaxHealthBonusExtraStacks * radiantMultiplier, itemCountEffective); } } }; CharacterBody.OnBuffFinalStackLost += (hook_OnBuffFinalStackLost)delegate(orig_OnBuffFinalStackLost orig, CharacterBody self, BuffDef buffDef) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, buffDef); if ((Object)(object)buffDef == (Object)(object)cooldownBuff) { self.healthComponent.Heal(self.maxHealth * percentHealingPerTick, default(ProcChainMask), true); Utilities.SpawnHealEffect(self); if (Object.op_Implicit((Object)(object)self.inventory) && self.inventory.GetItemCountEffective(def) > 0) { self.AddTimedBuff(cooldownBuff, tickDuration.Value); } } }; } internal static void FixedUpdateHook(CharacterBody body, int stack, BuffDef buff) { if (Object.op_Implicit((Object)(object)body) && body.GetBuffCount(buff) == 0 && stack > 0) { body.AddTimedBuff(buff, tickDuration.Value); } } } internal class GuinsoosRageblade { public class Statistics : MonoBehaviour { public class Sync : INetMessage, ISerializableObject { private NetworkInstanceId objId; private GameObject lastTarget; public Sync() { } public Sync(NetworkInstanceId objId, GameObject tick) { //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) this.objId = objId; lastTarget = tick; } public void Deserialize(NetworkReader reader) { //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) objId = reader.ReadNetworkId(); lastTarget = reader.ReadGameObject(); } public void OnReceived() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } GameObject val = Util.FindNetworkObject(objId); if ((Object)(object)val != (Object)null) { Statistics component = val.GetComponent<Statistics>(); if ((Object)(object)component != (Object)null) { component.LastTarget = lastTarget; } } } public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) writer.Write(objId); writer.Write(lastTarget); writer.FinishMessage(); } } private GameObject _lastTarget; public GameObject LastTarget { get { return _lastTarget; } set { //IL_001d: Unknown result type (might be due to invalid IL or missing references) _lastTarget = value; if (NetworkServer.active) { NetMessageExtensions.Send((INetMessage)(object)new Sync(((Component)this).gameObject.GetComponent<NetworkIdentity>().netId, value), (NetworkDestination)1); } } } } public static ItemDef itemDef; public static BuffDef wrathBuff; public static ItemDef radiantDef; public static ConfigurableValue<bool> isEnabled = new ConfigurableValue<bool>("Item: Guinsoos Rageblade", "Enabled", defaultValue: t