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 HalcyonShrineBestGrill v0.1.0
HalcyonShrineBestGrill/HalcyonShrineBestGrill.dll
Decompiled 5 months agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; 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 System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HG.Reflection; using HalcyonShrineBestGrill.Items; using Microsoft.CodeAnalysis; using On.RoR2; using R2API; using RoR2; using RoR2.Items; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HalcyonShrineBestGrill")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("HalcyonShrineBestGrill")] [assembly: AssemblyTitle("HalcyonShrineBestGrill")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HalcyonShrineBestGrill { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.whitet.halcyonshrinebestgrill", "Halcyon Shrine Best Grill", "0.1.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static ConfigFile Conf; internal static string AssemblyDir; public readonly List<ItemBase> Items = new List<ItemBase>(); private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Conf = ((BaseUnityPlugin)this).Config; AssemblyDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); Type baseType = typeof(ItemBase); foreach (ItemBase item in (from t in Assembly.GetExecutingAssembly().GetTypes() where !t.IsAbstract && baseType.IsAssignableFrom(t) select (ItemBase)Activator.CreateInstance(t) into i orderby i.InitOrder select i).ToList()) { if (!((BaseUnityPlugin)this).Config.Bind<bool>(item.ConfigSection, "Enable Item?", item.EnabledByDefault, "Set to false to exclude this item from runs.").Value) { Logger.LogInfo((object)("Skipping disabled item: " + item.ItemName)); continue; } item.Init(((BaseUnityPlugin)this).Config); Items.Add(item); Logger.LogInfo((object)("Registered item: " + item.ItemName)); } Logger.LogInfo((object)string.Format("{0} loaded {1} items.", "Halcyon Shrine Best Grill", Items.Count)); } public static Sprite LoadSprite(string fileNameInIconsDir, float ppu = 100f) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_002e: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) byte[] array = File.ReadAllBytes(Path.Combine(AssemblyDir, "Icons", fileNameInIconsDir)); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; ImageConversion.LoadImage(val, array); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), ppu); } } public static class PluginInfo { public const string PLUGIN_GUID = "com.whitet.halcyonshrinebestgrill"; public const string PLUGIN_NAME = "Halcyon Shrine Best Grill"; public const string PLUGIN_VERSION = "0.1.0"; } } namespace HalcyonShrineBestGrill.Items { public class CrowbarSteak : ItemBase { public float HpThresholdPct; public float BaseDamagePct; public float StackDamagePct; public float BaseHp; public float StackHp; public override string ItemName => "Crowbar Taped to a Steak"; public override string ItemLangTokenName => "CROWBAR_STEAK"; public override string ItemPickupDesc => "Deal bonus damage to healthy enemies. Gain max health."; public override string ItemFullDescription => $"Deal <style=cIsDamage>{BaseDamagePct}%</style> <style=cStack>(+{StackDamagePct}% per stack)</style> " + $"TOTAL bonus damage to enemies above <style=cIsDamage>{HpThresholdPct}%</style> health. " + $"Gain <style=cIsHealing>{BaseHp}</style> <style=cStack>(+{StackHp} per stack)</style> maximum health."; public override string ItemLore => "Engineering at its finest."; public override ItemTier Tier => (ItemTier)0; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2] { (ItemTag)1, (ItemTag)2 }; public override string IconFileName => "texCrowbarSteak.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; HpThresholdPct = config.Bind<float>(configSection, "HP Threshold %", 90f, "Victim must be above this % of full combined HP for the damage bonus.").Value; BaseDamagePct = config.Bind<float>(configSection, "Base Damage %", 30f, "First-stack bonus damage vs healthy enemies (% of total damage).").Value; StackDamagePct = config.Bind<float>(configSection, "Stack Damage %", 15f, "Additional bonus damage per stack (%).").Value; BaseHp = config.Bind<float>(configSection, "Base Max HP", 15f, "First-stack max HP bonus.").Value; StackHp = config.Bind<float>(configSection, "Stack Max HP", 15f, "Additional max HP per stack.").Value; } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats); } private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown orig.Invoke(self, di, victim); if (!NetworkServer.active || di == null || (Object)(object)di.attacker == (Object)null || (Object)(object)victim == (Object)null || di.procCoefficient <= 0f) { return; } CharacterBody component = di.attacker.GetComponent<CharacterBody>(); if ((Object)(object)((component != null) ? component.inventory : null) == (Object)null) { return; } int itemCount = component.inventory.GetItemCount(ItemDef); if (itemCount > 0) { HealthComponent component2 = victim.GetComponent<HealthComponent>(); if (!((Object)(object)component2 == (Object)null) && !(component2.fullCombinedHealth <= 0f) && !((component2.combinedHealth + di.damage) / component2.fullCombinedHealth < HpThresholdPct / 100f)) { float num = ItemBase.FirstThenPerStack(itemCount, BaseDamagePct, StackDamagePct) / 100f; DamageInfo val = new DamageInfo { damage = di.damage * num, attacker = di.attacker, inflictor = di.attacker, crit = false, damageColorIndex = (DamageColorIndex)3, damageType = DamageTypeCombo.op_Implicit((DamageType)0), procCoefficient = 0f, position = di.position, procChainMask = di.procChainMask }; component2.TakeDamage(val); } } } private void OnGetStats(CharacterBody body, StatHookEventArgs args) { int count = GetCount(body); if (count > 0) { args.baseHealthAdd += ItemBase.FirstThenPerStack(count, BaseHp, StackHp); } } } public class Edgekeeper : ItemBase { public class EdgekeeperBehavior : BaseItemBodyBehavior { private float timer; [ItemDefAssociation(useOnServer = true, useOnClient = false)] private static ItemDef GetItemDef() { return Instance?.ItemDef; } private void FixedUpdate() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Instance != null && !((Object)(object)((BaseItemBodyBehavior)this).body == (Object)null)) { timer += Time.fixedDeltaTime; if (!(timer < Instance.TickInterval)) { timer = 0f; int num = CountWoundedNearby(); ((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.FocusBuff.buffIndex, num); } } } private int CountWoundedNearby() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) int num = 0; Vector3 corePosition = ((BaseItemBodyBehavior)this).body.corePosition; float num2 = Instance.Radius * Instance.Radius; ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers((TeamIndex)2); for (int i = 0; i < teamMembers.Count; i++) { TeamComponent val = teamMembers[i]; if ((Object)(object)val == (Object)null) { continue; } CharacterBody body = val.body; HealthComponent val2 = ((body != null) ? body.healthComponent : null); if ((Object)(object)val2 == (Object)null || !val2.alive) { continue; } float fullCombinedHealth = val2.fullCombinedHealth; if (fullCombinedHealth <= 0f || val2.combinedHealth / fullCombinedHealth >= 1f) { continue; } Vector3 val3 = ((Component)val).transform.position - corePosition; if (!(((Vector3)(ref val3)).sqrMagnitude > num2)) { num++; if (num >= Instance.MaxStacks) { return num; } } } return num; } private void OnDisable() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Instance != null && (Object)(object)((BaseItemBodyBehavior)this).body != (Object)null && (Object)(object)Instance.FocusBuff != (Object)null) { ((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.FocusBuff.buffIndex, 0); } } } public static Edgekeeper Instance; public BuffDef FocusBuff; public float Radius; public float TickInterval; public int MaxStacks; public float BaseDamagePct; public float StackDamagePct; public override string ItemName => "The Edgekeeper"; public override string ItemLangTokenName => "EDGEKEEPER"; public override string ItemPickupDesc => "Gain bonus damage for each nearby wounded enemy."; public override string ItemFullDescription => $"Gain <style=cIsDamage>{BaseDamagePct}%</style> <style=cStack>(+{StackDamagePct}% per stack)</style> " + "bonus damage for each nearby enemy that is wounded but still alive. " + $"Scans within <style=cIsUtility>{Radius}m</style>, up to {MaxStacks} enemies."; public override string ItemLore => "Almost. Almost. Almost. ...Almost."; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)1 }; public override string IconFileName => "texLuckyPenny.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; public override bool EnabledByDefault => false; public override void Init(ConfigFile config) { Instance = this; base.Init(config); } protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; Radius = config.Bind<float>(configSection, "Radius", 25f, "Scan radius for wounded enemies (meters).").Value; TickInterval = config.Bind<float>(configSection, "Tick Interval", 0.25f, "Seconds between scans.").Value; MaxStacks = config.Bind<int>(configSection, "Max Stacks", 20, "Maximum wounded-enemy stacks.").Value; BaseDamagePct = config.Bind<float>(configSection, "Base Damage %", 2f, "First-stack damage bonus per wounded enemy (%).").Value; StackDamagePct = config.Bind<float>(configSection, "Stack Damage %", 1f, "Additional damage bonus per item stack per wounded enemy (%).").Value; } protected override void CreateBuffs() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) FocusBuff = ScriptableObject.CreateInstance<BuffDef>(); ((Object)FocusBuff).name = "HSBG_EdgekeeperFocus"; FocusBuff.canStack = true; FocusBuff.isDebuff = false; FocusBuff.isCooldown = false; FocusBuff.iconSprite = ItemDef.pickupIconSprite; FocusBuff.buffColor = new Color(0.2f, 0.95f, 0.55f); ContentAddition.AddBuffDef(FocusBuff); } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats); } private void OnGetStats(CharacterBody body, StatHookEventArgs args) { if ((Object)(object)body == (Object)null || (Object)(object)FocusBuff == (Object)null) { return; } int count = GetCount(body); if (count > 0) { int buffCount = body.GetBuffCount(FocusBuff); if (buffCount > 0) { float num = ItemBase.FirstThenPerStack(count, BaseDamagePct, StackDamagePct); args.damageMultAdd += num / 100f * (float)buffCount; } } } } public class Hatemace : ItemBase { public BuffDef HateDebuff; public float BaseChance; public float StackChance; public float BaseDuration; public float StackDuration; public float DamageBonusPct; public override string ItemName => "Hatemace"; public override string ItemLangTokenName => "HATEMACE"; public override string ItemPickupDesc => "Chance on hit to make enemies take increased damage from all sources."; public override string ItemFullDescription => $"<style=cIsDamage>{BaseChance}%</style> chance <style=cStack>(+{StackChance}% per stack)</style> on hit to apply " + $"<style=cIsDamage>Hated</style> for <style=cIsUtility>{BaseDuration}s</style> " + $"<style=cStack>(+{StackDuration}s per stack)</style>. Hated enemies take " + $"<style=cIsDamage>{DamageBonusPct}%</style> more damage from all sources."; public override string ItemLore => "Forged in the Spaceking's fury. It doesn't solve problems. It IS the problem."; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)1 }; public override string IconFileName => "texHatemace.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; BaseChance = config.Bind<float>(configSection, "Base Chance", 10f, "First-stack proc chance (%).").Value; StackChance = config.Bind<float>(configSection, "Stack Chance", 5f, "Additional proc chance per stack (%).").Value; BaseDuration = config.Bind<float>(configSection, "Base Duration", 4f, "First-stack debuff duration (seconds).").Value; StackDuration = config.Bind<float>(configSection, "Stack Duration", 1f, "Additional debuff duration per stack (seconds).").Value; DamageBonusPct = config.Bind<float>(configSection, "Damage Bonus %", 20f, "Bonus damage victims take while Hated (%).").Value; } protected override void CreateBuffs() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) HateDebuff = ScriptableObject.CreateInstance<BuffDef>(); ((Object)HateDebuff).name = "HSBG_Hated"; HateDebuff.canStack = false; HateDebuff.isDebuff = true; HateDebuff.isCooldown = false; HateDebuff.iconSprite = ItemDef.pickupIconSprite; HateDebuff.buffColor = new Color(0.7f, 0.1f, 0.1f); ContentAddition.AddBuffDef(HateDebuff); } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit); HealthComponent.TakeDamage += new hook_TakeDamage(OnTakeDamage); } private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim) { orig.Invoke(self, di, victim); if (!NetworkServer.active || di == null || (Object)(object)di.attacker == (Object)null || (Object)(object)victim == (Object)null || di.procCoefficient <= 0f) { return; } CharacterBody component = di.attacker.GetComponent<CharacterBody>(); if ((Object)(object)((component != null) ? component.inventory : null) == (Object)null) { return; } int itemCount = component.inventory.GetItemCount(ItemDef); if (itemCount > 0 && Util.CheckRoll(ItemBase.FirstThenPerStack(itemCount, BaseChance, StackChance) * di.procCoefficient, component.master)) { CharacterBody component2 = victim.GetComponent<CharacterBody>(); if (!((Object)(object)component2 == (Object)null)) { float num = ItemBase.FirstThenPerStack(itemCount, BaseDuration, StackDuration); component2.AddTimedBuff(HateDebuff, num); } } } private void OnTakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo di) { if (NetworkServer.active && (Object)(object)self != (Object)null && di != null && (Object)(object)self.body != (Object)null && (Object)(object)HateDebuff != (Object)null && self.body.HasBuff(HateDebuff)) { di.damage *= 1f + DamageBonusPct / 100f; } orig.Invoke(self, di); } } public abstract class ItemBase { public ItemDef ItemDef; public abstract string ItemName { get; } public abstract string ItemLangTokenName { get; } public abstract string ItemPickupDesc { get; } public abstract string ItemFullDescription { get; } public abstract string ItemLore { get; } public abstract ItemTier Tier { get; } public virtual ItemTag[] ItemTags => Array.Empty<ItemTag>(); public abstract string IconFileName { get; } public abstract string PickupModelAddress { get; } public virtual int InitOrder => 0; public virtual bool EnabledByDefault => true; public string ConfigSection => "Item: " + Regex.Replace(ItemName, "[=\\n\\t\\\\\"'\\[\\]]", ""); public virtual void Init(ConfigFile config) { CreateConfig(config); CreateLang(); CreateItem(); CreateBuffs(); Hooks(); } protected virtual void CreateConfig(ConfigFile config) { } protected virtual void CreateBuffs() { } protected void CreateLang() { LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_NAME", ItemName); LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_PICKUP", ItemPickupDesc); LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_DESCRIPTION", ItemFullDescription); LanguageAPI.Add("ITEM_" + ItemLangTokenName + "_LORE", ItemLore); } protected void CreateItem() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown ItemDef = ScriptableObject.CreateInstance<ItemDef>(); ((Object)ItemDef).name = "ITEM_" + ItemLangTokenName; ItemDef.nameToken = "ITEM_" + ItemLangTokenName + "_NAME"; ItemDef.pickupToken = "ITEM_" + ItemLangTokenName + "_PICKUP"; ItemDef.descriptionToken = "ITEM_" + ItemLangTokenName + "_DESCRIPTION"; ItemDef.loreToken = "ITEM_" + ItemLangTokenName + "_LORE"; ItemDef.tags = ItemTags; ItemDef.deprecatedTier = Tier; ItemDef.canRemove = true; ItemDef.hidden = false; ItemDef.pickupIconSprite = Plugin.LoadSprite(IconFileName); ItemDef.pickupModelPrefab = Addressables.LoadAssetAsync<GameObject>((object)PickupModelAddress).WaitForCompletion(); ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null))); } protected abstract void Hooks(); public int GetCount(CharacterBody body) { if (!Object.op_Implicit((Object)(object)((body != null) ? body.inventory : null))) { return 0; } return body.inventory.GetItemCount(ItemDef); } public static float FirstThenPerStack(int count, float firstStack, float perAdditional) { if (count > 0) { return firstStack + perAdditional * (float)(count - 1); } return 0f; } } public class PippinsChonkArmor : ItemBase { public float BaseHp; public float StackHp; public float BaseSlowPct; public float StackSlowPct; public float MaxSlowPct; public override string ItemName => "Pippin's Chonk Armor"; public override string ItemLangTokenName => "PIPPINS_CHONK_ARMOR"; public override string ItemPickupDesc => "Greatly increase maximum health. Reduce movement speed."; public override string ItemFullDescription => $"Gain <style=cIsHealing>{BaseHp}</style> <style=cStack>(+{StackHp} per stack)</style> maximum health. " + $"<style=cIsHealth>Reduce movement speed</style> by <style=cIsHealth>{BaseSlowPct}%</style> " + $"<style=cStack>(+{StackSlowPct}% per stack, capped at {MaxSlowPct}%)</style>."; public override string ItemLore => "Small. Fat. Immovable."; public override ItemTier Tier => (ItemTier)0; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2] { (ItemTag)2, (ItemTag)3 }; public override string IconFileName => "texLuckyPenny.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; public override bool EnabledByDefault => false; protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; BaseHp = config.Bind<float>(configSection, "Base Max HP", 37f, "First-stack max HP bonus.").Value; StackHp = config.Bind<float>(configSection, "Stack Max HP", 37f, "Additional max HP per stack.").Value; BaseSlowPct = config.Bind<float>(configSection, "Base Slow %", 5f, "First-stack move speed reduction (%).").Value; StackSlowPct = config.Bind<float>(configSection, "Stack Slow %", 5f, "Additional move speed reduction per stack (%).").Value; MaxSlowPct = config.Bind<float>(configSection, "Max Slow %", 50f, "Ceiling on total move speed reduction (%).").Value; } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats); } private void OnGetStats(CharacterBody body, StatHookEventArgs args) { int count = GetCount(body); if (count > 0) { args.baseHealthAdd += ItemBase.FirstThenPerStack(count, BaseHp, StackHp); float num = Mathf.Min(ItemBase.FirstThenPerStack(count, BaseSlowPct, StackSlowPct), MaxSlowPct); args.moveSpeedMultAdd -= num / 100f; } } } public class SiliconeMassager : ItemBase { public BuffDef RegenBuff; public float BaseRegen; public float StackRegen; public float Duration; public override string ItemName => "Silicone Face Lifting Massager"; public override string ItemLangTokenName => "SILICONE_MASSAGER"; public override string ItemPickupDesc => "On taking damage, briefly gain regeneration."; public override string ItemFullDescription => $"Upon taking damage, gain <style=cIsHealing>{BaseRegen} HP/s</style> " + $"<style=cStack>(+{StackRegen} HP/s per stack)</style> regeneration for " + $"<style=cIsUtility>{Duration}s</style>."; public override string ItemLore => "Imported. Discreet packaging. 'Therapeutic use only.'"; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[1] { (ItemTag)2 }; public override string IconFileName => "texSiliconeMassager.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; BaseRegen = config.Bind<float>(configSection, "Base Regen", 8f, "First-stack regen while buff is active (HP/s).").Value; StackRegen = config.Bind<float>(configSection, "Stack Regen", 2f, "Additional regen per stack (HP/s).").Value; Duration = config.Bind<float>(configSection, "Duration", 4f, "Buff duration after a damage hit (seconds).").Value; } protected override void CreateBuffs() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) RegenBuff = ScriptableObject.CreateInstance<BuffDef>(); ((Object)RegenBuff).name = "HSBG_SiliconeRegen"; RegenBuff.canStack = true; RegenBuff.isDebuff = false; RegenBuff.isCooldown = false; RegenBuff.iconSprite = ItemDef.pickupIconSprite; RegenBuff.buffColor = new Color(1f, 0.6f, 0.85f); ContentAddition.AddBuffDef(RegenBuff); } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown HealthComponent.TakeDamage += new hook_TakeDamage(OnTakeDamage); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats); } private void OnTakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo di) { orig.Invoke(self, di); if (NetworkServer.active && !((Object)(object)self == (Object)null) && di != null && !(di.damage <= 0f)) { CharacterBody body = self.body; if (!((Object)(object)body == (Object)null) && !((Object)(object)body.inventory == (Object)null) && body.inventory.GetItemCount(ItemDef) > 0) { body.AddTimedBuff(RegenBuff, Duration); } } } private void OnGetStats(CharacterBody body, StatHookEventArgs args) { if (!((Object)(object)body == (Object)null) && !((Object)(object)RegenBuff == (Object)null) && body.GetBuffCount(RegenBuff) > 0) { int count = GetCount(body); if (count > 0) { args.baseRegenAdd += ItemBase.FirstThenPerStack(count, BaseRegen, StackRegen); } } } } public class TwoMeatPatties : ItemBase { public class TwoMeatPattiesBehavior : BaseItemBodyBehavior { private float timer; [ItemDefAssociation(useOnServer = true, useOnClient = false)] private static ItemDef GetItemDef() { return Instance?.ItemDef; } private void FixedUpdate() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || Instance == null || (Object)(object)((BaseItemBodyBehavior)this).body == (Object)null || (Object)(object)Instance.SafeBuff == (Object)null) { return; } timer += Time.fixedDeltaTime; if (!(timer < Instance.TickInterval)) { timer = 0f; bool flag = !AnyEnemyWithin(Instance.SafeRadius); bool flag2 = ((BaseItemBodyBehavior)this).body.HasBuff(Instance.SafeBuff); if (flag != flag2) { ((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.SafeBuff.buffIndex, flag ? 1 : 0); ((BaseItemBodyBehavior)this).body.MarkAllStatsDirty(); } } } private bool AnyEnemyWithin(float radius) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Vector3 corePosition = ((BaseItemBodyBehavior)this).body.corePosition; float num = radius * radius; ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers((TeamIndex)2); for (int i = 0; i < teamMembers.Count; i++) { TeamComponent val = teamMembers[i]; if ((Object)(object)val == (Object)null) { continue; } CharacterBody body = val.body; HealthComponent val2 = ((body != null) ? body.healthComponent : null); if (!((Object)(object)val2 == (Object)null) && val2.alive) { Vector3 val3 = ((Component)val).transform.position - corePosition; if (((Vector3)(ref val3)).sqrMagnitude <= num) { return true; } } } return false; } private void OnDisable() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Instance != null && (Object)(object)((BaseItemBodyBehavior)this).body != (Object)null && (Object)(object)Instance.SafeBuff != (Object)null && ((BaseItemBodyBehavior)this).body.HasBuff(Instance.SafeBuff)) { ((BaseItemBodyBehavior)this).body.SetBuffCount(Instance.SafeBuff.buffIndex, 0); ((BaseItemBodyBehavior)this).body.MarkAllStatsDirty(); } } } public static TwoMeatPatties Instance; public BuffDef SafeBuff; public float BaseHp; public float StackHp; public float BaseRegen; public float StackRegen; public float BaseSafeRegen; public float StackSafeRegen; public float SafeRadius; public float TickInterval; public override string ItemName => "Two Meat Patties"; public override string ItemLangTokenName => "TWO_MEAT_PATTIES"; public override string ItemPickupDesc => "Increase max health. Regenerate much faster when no enemies are near."; public override string ItemFullDescription => $"Gain <style=cIsHealing>{BaseHp}</style> <style=cStack>(+{StackHp} per stack)</style> maximum health " + $"and <style=cIsHealing>{BaseRegen} HP/s</style> <style=cStack>(+{StackRegen} HP/s per stack)</style> base regeneration. " + $"While no enemies are within <style=cIsUtility>{SafeRadius}m</style>, gain " + $"<style=cIsHealing>{BaseSafeRegen} HP/s</style> <style=cStack>(+{StackSafeRegen} HP/s per stack)</style> bonus regeneration."; public override string ItemLore => "No bun. No lettuce. Just meat."; public override ItemTier Tier => (ItemTier)0; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2] { (ItemTag)2, (ItemTag)3 }; public override string IconFileName => "texTwoMeatPatties.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; public override void Init(ConfigFile config) { Instance = this; base.Init(config); } protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; BaseHp = config.Bind<float>(configSection, "Base Max HP", 25f, "First-stack max HP bonus.").Value; StackHp = config.Bind<float>(configSection, "Stack Max HP", 25f, "Additional max HP per stack.").Value; BaseRegen = config.Bind<float>(configSection, "Base Regen", 1f, "First-stack base regen bonus (HP/s).").Value; StackRegen = config.Bind<float>(configSection, "Stack Regen", 1f, "Additional regen per stack (HP/s).").Value; BaseSafeRegen = config.Bind<float>(configSection, "Base Safe Regen", 10f, "First-stack bonus regen while no enemies nearby (HP/s).").Value; StackSafeRegen = config.Bind<float>(configSection, "Stack Safe Regen", 10f, "Additional bonus regen per stack while safe (HP/s).").Value; SafeRadius = config.Bind<float>(configSection, "Safe Radius", 30f, "Enemy-free radius required for bonus regen (meters).").Value; TickInterval = config.Bind<float>(configSection, "Tick Interval", 0.25f, "Seconds between proximity scans.").Value; } protected override void CreateBuffs() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) SafeBuff = ScriptableObject.CreateInstance<BuffDef>(); ((Object)SafeBuff).name = "HSBG_TwoMeatPattiesSafe"; SafeBuff.canStack = false; SafeBuff.isDebuff = false; SafeBuff.isCooldown = false; SafeBuff.iconSprite = ItemDef.pickupIconSprite; SafeBuff.buffColor = new Color(0.95f, 0.55f, 0.35f); ContentAddition.AddBuffDef(SafeBuff); } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats); } private void OnGetStats(CharacterBody body, StatHookEventArgs args) { int count = GetCount(body); if (count > 0) { args.baseHealthAdd += ItemBase.FirstThenPerStack(count, BaseHp, StackHp); args.baseRegenAdd += ItemBase.FirstThenPerStack(count, BaseRegen, StackRegen); if ((Object)(object)SafeBuff != (Object)null && body.HasBuff(SafeBuff)) { args.baseRegenAdd += ItemBase.FirstThenPerStack(count, BaseSafeRegen, StackSafeRegen); } } } } public class Tylanol : ItemBase { public float BaseProcPct; public float StackProcPct; public float BaseSlowPct; public float StackSlowPct; public float MaxSlowPct; public override string ItemName => "Tylanol"; public override string ItemLangTokenName => "TYLANOL"; public override string ItemPickupDesc => "Increase all item proc coefficients. Reduce movement speed."; public override string ItemFullDescription => $"Increase all outgoing proc coefficients by <style=cIsDamage>{BaseProcPct}%</style> " + $"<style=cStack>(+{StackProcPct}% per stack)</style>. " + $"<style=cIsHealth>Reduce movement speed</style> by <style=cIsHealth>{BaseSlowPct}%</style> " + $"<style=cStack>(+{StackSlowPct}% per stack, capped at {MaxSlowPct}%)</style>."; public override string ItemLore => "Side effects may include heightened pattern recognition and an inability to make eye contact."; public override ItemTier Tier => (ItemTier)1; public override ItemTag[] ItemTags => (ItemTag[])(object)new ItemTag[2] { (ItemTag)1, (ItemTag)3 }; public override string IconFileName => "texLuckyPenny.png"; public override string PickupModelAddress => "RoR2/Base/Bear/PickupBear.prefab"; public override bool EnabledByDefault => false; public override int InitOrder => 100; protected override void CreateConfig(ConfigFile config) { string configSection = base.ConfigSection; BaseProcPct = config.Bind<float>(configSection, "Base Proc %", 15f, "First-stack proc coefficient increase (%).").Value; StackProcPct = config.Bind<float>(configSection, "Stack Proc %", 15f, "Additional proc coefficient increase per stack (%).").Value; BaseSlowPct = config.Bind<float>(configSection, "Base Slow %", 3f, "First-stack move speed reduction (%).").Value; StackSlowPct = config.Bind<float>(configSection, "Stack Slow %", 3f, "Additional move speed reduction per stack (%).").Value; MaxSlowPct = config.Bind<float>(configSection, "Max Slow %", 100f, "Ceiling on total move speed reduction (%).").Value; } protected override void Hooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown GlobalEventManager.OnHitEnemy += new hook_OnHitEnemy(OnHit); RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(OnGetStats); } private void OnHit(orig_OnHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim) { if (di == null || (Object)(object)di.attacker == (Object)null || di.procCoefficient <= 0f) { orig.Invoke(self, di, victim); return; } CharacterBody component = di.attacker.GetComponent<CharacterBody>(); if ((Object)(object)((component != null) ? component.inventory : null) == (Object)null) { orig.Invoke(self, di, victim); return; } int itemCount = component.inventory.GetItemCount(ItemDef); if (itemCount <= 0) { orig.Invoke(self, di, victim); return; } float procCoefficient = di.procCoefficient; float num = 1f + ItemBase.FirstThenPerStack(itemCount, BaseProcPct, StackProcPct) / 100f; di.procCoefficient = procCoefficient * num; try { orig.Invoke(self, di, victim); } finally { di.procCoefficient = procCoefficient; } } private void OnGetStats(CharacterBody body, StatHookEventArgs args) { int count = GetCount(body); if (count > 0) { float num = Mathf.Min(ItemBase.FirstThenPerStack(count, BaseSlowPct, StackSlowPct), MaxSlowPct); args.moveSpeedMultAdd -= num / 100f; } } } }