using 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 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 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(((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, 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(); } 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(val, centerPoint, Quaternion.identity); } float num = c.GetMaxHealth() / 3f; List 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 nviewRef = AccessTools.FieldRefAccess("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() == (Object)null) { ((Component)c).gameObject.AddComponent(); } 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(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 MaxStars; internal static readonly ConfigEntry[] StarChances = new ConfigEntry[6]; internal static ConfigEntry SizePerStar; internal static ConfigEntry SizeInDungeons; internal static ConfigEntry InfusionsEnabled; internal static readonly ConfigEntry[] InfusionChance = new ConfigEntry[6]; internal static ConfigEntry InfusionPerStar; internal static ConfigEntry InfusionInName; internal static ConfigEntry TintBrightness; internal static ConfigEntry 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("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(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("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("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(0f, 1f))); SizeInDungeons = ((BaseUnityPlugin)this).Config.Bind("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("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("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(0f, 100f))); } InfusionPerStar = ((BaseUnityPlugin)this).Config.Bind("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("Infusions", "Add the infusion to the name", true, "Shows 'Fire-Infused Greydwarf' in the enemy nameplate. Client-side."); TintBrightness = ((BaseUnityPlugin)this).Config.Bind("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(0f, 4f), Array.Empty())); LogRolls = ((BaseUnityPlugin)this).Config.Bind("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])); } } } }