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 ReefLevels v0.1.0
ReefLevels.dll
Decompiled 3 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ReefLevels")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+523a001dd61578f32898283ab8d4550ef81782b9")] [assembly: AssemblyProduct("ReefLevels")] [assembly: AssemblyTitle("ReefLevels")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ReefLevels { internal static class Display { [HarmonyPatch(typeof(LevelEffects), "SetupLevelVisualization", new Type[] { typeof(int) })] internal static class LevelVisualization { private static void Prefix(LevelEffects __instance, int level) { try { List<LevelSetup> levelSetups = __instance.m_levelSetups; if (levelSetups != null && levelSetups.Count != 0) { while (levelSetups.Count < level - 1) { levelSetups.Add(levelSetups[levelSetups.Count - 1]); } } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("SetupLevelVisualization: " + ex.GetType().Name + ": " + ex.Message)); } } private static void Postfix(LevelEffects __instance, int level) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) try { List<LevelSetup> levelSetups = __instance.m_levelSetups; if (level > 1 && levelSetups != null && levelSetups.Count >= level - 1) { float value = ReefLevelsPlugin.SizePerStar.Value; if (!(value <= 0f) && (!(((Component)__instance).transform.position.y >= 4500f) || ReefLevelsPlugin.SizeInDungeons.Value)) { Transform transform = ((Component)__instance).transform; transform.localScale *= 1f + value * (float)(level - 1); } } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("SetupLevelVisualization: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(EnemyHud), "ShowHud", new Type[] { typeof(Character), typeof(bool) })] internal static class HudShow { private static void Postfix(EnemyHud __instance, Character c) { //IL_011c: Unknown result type (might be due to invalid IL or missing references) try { if (!(hudsField.GetValue(__instance) is IDictionary dictionary) || (Object)(object)c == (Object)null) { return; } object obj = dictionary[c]; if (obj == null) { return; } object? value = guiField.GetValue(obj); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null || (Object)(object)val.transform.Find("level_4") != (Object)null) { return; } Transform val2 = val.transform.Find("level_3"); if ((Object)(object)val2 == (Object)null || val2.childCount == 0) { return; } for (int i = 4; i <= 7; i++) { GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val2.parent); ((Object)val3).name = "level_" + i; val3.SetActive(false); GameObject gameObject = ((Component)val3.transform.GetChild(0)).gameObject; for (int j = 3; j <= i - 1; j++) { Object.Instantiate<GameObject>(gameObject, val3.transform).transform.localPosition = new Vector3(16f * (float)((j - 1) % 5) - 8f, (float)((j - 1) / 5) * -16f, 0f); } } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("EnemyHud.ShowHud: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(EnemyHud), "UpdateHuds", new Type[] { typeof(Player), typeof(Sadle), typeof(float) })] internal static class HudUpdate { private static void Postfix(EnemyHud __instance) { try { if (!(hudsField.GetValue(__instance) is IDictionary dictionary)) { return; } bool value = ReefLevelsPlugin.InfusionInName.Value; foreach (DictionaryEntry item in dictionary) { object key = item.Key; Character val = (Character)((key is Character) ? key : null); object value2 = item.Value; if ((Object)(object)val == (Object)null || value2 == null) { continue; } object? value3 = guiField.GetValue(value2); GameObject val2 = (GameObject)((value3 is GameObject) ? value3 : null); if ((Object)(object)val2 == (Object)null || !val2.activeSelf) { continue; } int level = val.GetLevel(); if (level >= 4) { Transform val3 = val2.transform.Find("level_" + Mathf.Min(level, 7)); if ((Object)(object)val3 != (Object)null && !((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(true); } } if (!value) { continue; } int num = Infusion.Of(val); if (num == 0) { continue; } object? value4 = nameField.GetValue(value2); TextMeshProUGUI val4 = (TextMeshProUGUI)((value4 is TextMeshProUGUI) ? value4 : null); if (!((Object)(object)val4 == (Object)null)) { string text = Infusion.Names[num] + "-Infused "; if (!((TMP_Text)val4).text.StartsWith(text, StringComparison.Ordinal)) { ((TMP_Text)val4).text = text + ((TMP_Text)val4).text; } } } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("EnemyHud.UpdateHuds: " + ex.GetType().Name + ": " + ex.Message)); } } } private static readonly FieldInfo hudsField = AccessTools.Field(typeof(EnemyHud), "m_huds"); private static readonly Type hudDataType = AccessTools.Inner(typeof(EnemyHud), "HudData"); private static readonly FieldInfo guiField = AccessTools.Field(hudDataType, "m_gui"); private static readonly FieldInfo nameField = AccessTools.Field(hudDataType, "m_name"); } internal static class Infusion { internal class ChaosTint : MonoBehaviour { private Character character; private float timer; private void Awake() { character = ((Component)this).GetComponent<Character>(); } private void Update() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) timer -= Time.deltaTime; if (!(timer > 0f)) { timer = 5f; if ((Object)(object)character != (Object)null) { Tint(character, TintOf(RandomElement())); } } } } [HarmonyPatch(typeof(Character), "SetLevel", new Type[] { typeof(int) })] internal static class CharacterSetLevel { private static void Postfix(Character __instance) { try { if (!__instance.IsPlayer()) { ApplyTint(__instance); } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("Character.SetLevel: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(Character), "Damage", new Type[] { typeof(HitData) })] internal static class CharacterDamage { private static void Prefix(Character __instance, HitData hit) { try { if (hit == null || inBurst || !ReefLevelsPlugin.InfusionsEnabled.Value) { return; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || attacker.IsPlayer() || attacker.IsBoss()) { return; } ZNetView val = NView(attacker); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return; } int num = Of(attacker); switch (num) { case 0: return; case 5: num = RandomElement(); break; } float totalDamage = hit.GetTotalDamage(); if (!(totalDamage <= 0f)) { float num2 = Mathf.Min(totalDamage, __instance.GetMaxHealth() * 0.33f); switch (num) { case 2: hit.ApplyModifier(1f - num2 / totalDamage); hit.m_damage.m_fire += num2; break; case 3: hit.ApplyModifier(1f - num2 / totalDamage); hit.m_damage.m_frost += num2; break; case 1: hit.ApplyModifier(1f - num2 / totalDamage); hit.m_damage.m_lightning += num2; break; case 6: hit.ApplyModifier(1f - num2 / totalDamage); hit.m_damage.m_damage += totalDamage * 0.3f; attacker.Heal(Mathf.Min(totalDamage, attacker.GetMaxHealth() * 0.3f), true); break; case 4: case 5: break; } } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("Character.Damage: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(Character), "OnDeath", new Type[] { })] internal static class CharacterOnDeath { private static void Prefix(Character __instance) { try { if (!ReefLevelsPlugin.InfusionsEnabled.Value || __instance.IsPlayer() || __instance.IsBoss()) { return; } ZNetView val = NView(__instance); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return; } switch (Of(__instance)) { case 5: if (!(Random.value < 0.5f)) { break; } goto case 4; case 4: Burst(__instance); break; } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("Character.OnDeath: " + ex.GetType().Name + ": " + ex.Message)); } } private static void Burst(Character c) { //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_0031: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0102: Unknown result type (might be due to invalid IL or missing references) Vector3 centerPoint = c.GetCenterPoint(); GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("vfx_blob_attack") : null); if ((Object)(object)val != (Object)null) { Object.Instantiate<GameObject>(val, centerPoint, Quaternion.identity); } float num = c.GetMaxHealth() / 3f; List<Player> allPlayers = Player.GetAllPlayers(); if (allPlayers == null) { return; } foreach (Player item in allPlayers) { if (!((Object)(object)item == (Object)null) && !(Vector3.Distance(((Component)item).transform.position, centerPoint) > 4f)) { float bodyArmor = ((Character)item).GetBodyArmor(); float num2 = num; if (bodyArmor > num2 / 4f) { num2 = Mathf.Sqrt(4f * bodyArmor * num2); } if (bodyArmor < num2 / 2f) { num2 = num + bodyArmor; } HitData val2 = new HitData(); val2.m_damage.m_poison = num2; val2.m_point = ((Character)item).GetCenterPoint(); val2.m_attacker = c.GetZDOID(); val2.m_hitType = (HitType)1; inBurst = true; try { ((Character)item).Damage(val2); } finally { inBurst = false; } } } } } internal const int None = 0; internal const int Lightning = 1; internal const int Fire = 2; internal const int Frost = 3; internal const int Poison = 4; internal const int Chaos = 5; internal const int Spirit = 6; internal static readonly string[] Names = new string[7] { "none", "Lightning", "Fire", "Frost", "Poison", "Chaos", "Spirit" }; internal static readonly int[] ConfigOrder = new int[6] { 2, 3, 4, 1, 6, 5 }; private static readonly int[] Elements = new int[5] { 1, 2, 3, 4, 6 }; private static readonly FieldRef<Character, ZNetView> nviewRef = AccessTools.FieldRefAccess<Character, ZNetView>("m_nview"); private static bool inBurst; internal static ZNetView NView(Character c) { if (!((Object)(object)c == (Object)null)) { return nviewRef.Invoke(c); } return null; } internal static int Draw(int stars) { if (!ReefLevelsPlugin.InfusionsEnabled.Value || stars < 1) { return 0; } float num = Roll.Parse(ReefLevelsPlugin.InfusionPerStar.Value, 6)[Mathf.Clamp(stars, 0, 5)]; float num2 = Random.value * 100f; float num3 = 0f; for (int i = 0; i < 6; i++) { num3 += ReefLevelsPlugin.InfusionChance[i].Value * num; if (num2 < num3) { return ConfigOrder[i]; } } return 0; } internal static int Of(Character c) { ZNetView val = NView(c); if ((Object)(object)val == (Object)null || !val.IsValid()) { return 0; } ZDO zDO = val.GetZDO(); int num = zDO.GetInt("ReefLevels.infusion", -1); if (num == -1) { num = zDO.GetInt("CL&LC infusion", -1); } if (num >= 0 && num <= 6) { return num; } return 0; } internal static int RandomElement() { return Elements[Random.Range(0, Elements.Length)]; } internal static Color TintOf(int inf) { //IL_005b: 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) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) return (Color)(inf switch { 2 => new Color(1f, 0.1f, 0f), 3 => new Color(0f, 0f, 1f), 1 => new Color(0.8f, 0.75f, 1f), 6 => new Color(1f, 0f, 1f), 4 => new Color(0f, 1f, 0f), _ => Color.white, }); } internal static void ApplyTint(Character c) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) int num = Of(c); switch (num) { case 0: break; case 5: if ((Object)(object)((Component)c).GetComponent<ChaosTint>() == (Object)null) { ((Component)c).gameObject.AddComponent<ChaosTint>(); } break; default: Tint(c, TintOf(num)); break; } } internal static void Tint(Character c, Color tint) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) float value = ReefLevelsPlugin.TintBrightness.Value; Color val = default(Color); ((Color)(ref val))..ctor(tint.r * value, tint.g * value, tint.b * value, 1f); MaterialPropertyBlock val2 = new MaterialPropertyBlock(); Renderer[] componentsInChildren = ((Component)c).GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { Material sharedMaterial = val3.sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null) { continue; } val2.Clear(); val3.GetPropertyBlock(val2); if (sharedMaterial.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", val); } else { if (!sharedMaterial.HasProperty("_Color")) { continue; } val2.SetColor("_Color", Color.Lerp(sharedMaterial.GetColor("_Color"), val, 0.5f)); } val3.SetPropertyBlock(val2); } } } [BepInPlugin("reef.levels", "Reef Levels", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ReefLevelsPlugin : BaseUnityPlugin { public const string GUID = "reef.levels"; public const string NAME = "Reef Levels"; public const string VERSION = "0.1.0"; internal const string CllcGuid = "org.bepinex.plugins.creaturelevelcontrol"; internal static ManualLogSource Log; internal static ConfigEntry<int> MaxStars; internal static readonly ConfigEntry<string>[] StarChances = new ConfigEntry<string>[6]; internal static ConfigEntry<float> SizePerStar; internal static ConfigEntry<bool> SizeInDungeons; internal static ConfigEntry<bool> InfusionsEnabled; internal static readonly ConfigEntry<float>[] InfusionChance = new ConfigEntry<float>[6]; internal static ConfigEntry<string> InfusionPerStar; internal static ConfigEntry<bool> InfusionInName; internal static ConfigEntry<float> TintBrightness; internal static ConfigEntry<bool> LogRolls; private Harmony harmony; private void Awake() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BindConfig(); if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.creaturelevelcontrol")) { Log.LogWarning((object)"Reef Levels 0.1.0: CreatureLevelControl is loaded next to us — no patch applied (its own roll and display would double ours)"); return; } if ((int)SystemInfo.graphicsDeviceType == 4) { Log.LogInfo((object)"Reef Levels 0.1.0: headless — config only, no patch"); return; } harmony = new Harmony("reef.levels"); harmony.PatchAll(typeof(Roll.SpawnSystemSpawn)); harmony.PatchAll(typeof(Roll.CreatureSpawnerSpawn)); harmony.PatchAll(typeof(Roll.SpawnAreaSpawnOne)); harmony.PatchAll(typeof(Roll.CharacterAwake)); harmony.PatchAll(typeof(Roll.CharacterSetLevelKeep)); harmony.PatchAll(typeof(Infusion.CharacterSetLevel)); harmony.PatchAll(typeof(Infusion.CharacterDamage)); harmony.PatchAll(typeof(Infusion.CharacterOnDeath)); harmony.PatchAll(typeof(Display.LevelVisualization)); harmony.PatchAll(typeof(Display.HudShow)); harmony.PatchAll(typeof(Display.HudUpdate)); Log.LogInfo((object)"Reef Levels 0.1.0 loaded"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private static ConfigDescription Admin(string text, AcceptableValueBase range = null) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(text, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } private void BindConfig() { //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Expected O, but got Unknown MaxStars = ((BaseUnityPlugin)this).Config.Bind<int>("Levels", "Maximum stars", 2, Admin("Natural creatures never roll more stars than this (0-5). The Reef: 2 today, 5 once ReefLevels is proven.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5))); string[] array = new string[6] { "10,2,0,0,0", "15,5,1,0,0", "18,8,2,0.3,0", "22,10,3,0.5,0.3", "25,12,5,1,0.5", "30,15,8,3,1" }; for (int i = 0; i < 6; i++) { StarChances[i] = ((BaseUnityPlugin)this).Config.Bind<string>("Levels", "Chances for stars at world level " + i, array[i], Admin("Percentages for 1, 2, 3, 4 and 5 stars at world level " + i + " (= number of bosses defeated among the first six; 6 uses this row too). The rest is 0 stars.")); } SizePerStar = ((BaseUnityPlugin)this).Config.Bind<float>("Levels", "Creature size increase per star", 0.1f, Admin("Creature scale grows by this fraction per star (0.10 = +10 % per star).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f))); SizeInDungeons = ((BaseUnityPlugin)this).Config.Bind<bool>("Levels", "Increase creature size in dungeons", false, Admin("true = the size increase also applies inside dungeons (y >= 4500), where big creatures get stuck.")); InfusionsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Infusions", "Enabled", true, Admin("Creatures with at least one star can roll an elemental infusion.")); string[] array2 = new string[6] { "Fire", "Frost", "Poison", "Lightning", "Spirit", "Chaos" }; float[] array3 = new float[6] { 7f, 7f, 4f, 3f, 1.75f, 1.25f }; for (int j = 0; j < 6; j++) { InfusionChance[j] = ((BaseUnityPlugin)this).Config.Bind<float>("Infusions", "Chance for " + array2[j], array3[j], Admin("Percent chance of a " + array2[j] + " infusion, multiplied by the per-star multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f))); } InfusionPerStar = ((BaseUnityPlugin)this).Config.Bind<string>("Infusions", "Multiplier per star", "0,0.3,0.6,1,1.3,1.6", Admin("Multiplier applied to every infusion chance for 0, 1, 2, 3, 4 and 5 stars.")); InfusionInName = ((BaseUnityPlugin)this).Config.Bind<bool>("Infusions", "Add the infusion to the name", true, "Shows 'Fire-Infused Greydwarf' in the enemy nameplate. Client-side."); TintBrightness = ((BaseUnityPlugin)this).Config.Bind<float>("Infusions", "Tint brightness", 0.3f, new ConfigDescription("Multiplier on the infusion tint colour applied to the creature (1 = full emission, the model reads as a flat colour — bench S030). Client-side.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>())); LogRolls = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log rolls", false, "Logs one line per creature rolled by this client: prefab, world level, stars, infusion. Client-side."); } } internal static class Roll { [HarmonyPatch(typeof(SpawnSystem), "Spawn", new Type[] { typeof(SpawnData), typeof(Vector3), typeof(bool) })] internal static class SpawnSystemSpawn { private static void Prefix() { Spawning++; } private static void Postfix() { Spawning--; } } [HarmonyPatch(typeof(CreatureSpawner), "Spawn", new Type[] { })] internal static class CreatureSpawnerSpawn { private static void Prefix() { Spawning++; } private static void Postfix() { Spawning--; } } [HarmonyPatch(typeof(SpawnArea), "SpawnOne", new Type[] { })] internal static class SpawnAreaSpawnOne { private static void Prefix() { Spawning++; } private static void Postfix() { Spawning--; } } [HarmonyPatch(typeof(Character), "Awake", new Type[] { })] internal static class CharacterAwake { private static void Postfix(Character __instance) { try { if (__instance.IsPlayer()) { return; } ZNetView val = Infusion.NView(__instance); if (!((Object)(object)val == (Object)null) && val.IsValid()) { ZDO zDO = val.GetZDO(); if (Spawning > 0 && val.IsOwner() && !__instance.IsTamed() && !__instance.IsBoss() && zDO.GetInt("ReefLevels.rolled", -1) == -1 && zDO.GetInt("CL&LC effect", -1) == -1 && zDO.GetInt("CL&LC infusion", -1) == -1) { RollOne(__instance, zDO); } Infusion.ApplyTint(__instance); } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("Character.Awake: " + ex.GetType().Name + ": " + ex.Message)); } } } [HarmonyPatch(typeof(Character), "SetLevel", new Type[] { typeof(int) })] internal static class CharacterSetLevelKeep { private static void Prefix(Character __instance, ref int level) { try { if (Spawning <= 0 || __instance.IsPlayer()) { return; } ZNetView val = Infusion.NView(__instance); if (!((Object)(object)val == (Object)null) && val.IsValid()) { int num = val.GetZDO().GetInt("ReefLevels.level", -1); if (num >= 1 && level != num) { level = num; } } } catch (Exception ex) { ReefLevelsPlugin.Log.LogWarning((object)("Character.SetLevel(keep): " + ex.GetType().Name + ": " + ex.Message)); } } } internal const string KeyRolled = "ReefLevels.rolled"; internal const string KeyInfusion = "ReefLevels.infusion"; internal const string KeyLevel = "ReefLevels.level"; internal const string CllcEffect = "CL&LC effect"; internal const string CllcInfusion = "CL&LC infusion"; private static readonly string[] BossKeys = new string[6] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen" }; internal static int Spawning; internal static int WorldLevel() { ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance == (Object)null) { return 0; } int num = 0; string[] bossKeys = BossKeys; foreach (string text in bossKeys) { if (instance.GetGlobalKey(text)) { num++; } } return num; } internal static float[] Parse(string s, int count) { float[] array = new float[count]; string[] array2 = (s ?? "").Split(new char[1] { ',' }); for (int i = 0; i < count && i < array2.Length; i++) { array[i] = (float.TryParse(array2[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) ? result : 0f); } return array; } internal static int DrawStars(int worldLevel) { float[] array = Parse(ReefLevelsPlugin.StarChances[Mathf.Clamp(worldLevel, 0, 5)].Value, 5); float num = Random.value * 100f; float num2 = 0f; int num3 = 0; for (int num4 = 5; num4 >= 1; num4--) { num2 += array[num4 - 1]; if (num < num2) { num3 = num4; break; } } return Mathf.Clamp(num3, 0, ReefLevelsPlugin.MaxStars.Value); } internal static string PrefabName(Character c) { string name = ((Object)((Component)c).gameObject).name; int num = name.IndexOf("(Clone)", StringComparison.Ordinal); if (num <= 0) { return name; } return name.Substring(0, num); } private static void RollOne(Character c, ZDO zdo) { int worldLevel = WorldLevel(); int num = DrawStars(worldLevel); int num2 = Infusion.Draw(num); zdo.Set("ReefLevels.infusion", num2); zdo.Set("ReefLevels.level", num + 1); zdo.Set("ReefLevels.rolled", 1); c.SetLevel(num + 1); if (ReefLevelsPlugin.LogRolls.Value) { ReefLevelsPlugin.Log.LogInfo((object)("ReefLevels: " + PrefabName(c) + " wl=" + worldLevel + " stars=" + num + " infusion=" + Infusion.Names[num2])); } } } }