Decompiled source of BossStarsAfterDefeat v2.0.3

BossStarsAfterDefeat.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("BossStarsAfterDefeat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BossStarsAfterDefeat")]
[assembly: AssemblyTitle("BossStarsAfterDefeat")]
[assembly: AssemblyVersion("1.0.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 BossStarsAfterDefeat
{
	[BepInPlugin("pieter.valheim.bossstarsafterdefeat", "Boss Stars After Defeat", "2.0.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "pieter.valheim.bossstarsafterdefeat";

		public const string Name = "Boss Stars After Defeat";

		public const string Version = "2.0.3";

		private const string StarLevelSystemGuid = "MidnightsFX.StarLevelSystem";

		private const string EpicLootGuid = "randyknapp.mods.epicloot";

		private static readonly string[] BossKeys = new string[8] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader", "defeated_frozenking_p3" };

		private static readonly Dictionary<Biome, int> BiomeIndex = new Dictionary<Biome, int>
		{
			{
				(Biome)1,
				0
			},
			{
				(Biome)8,
				1
			},
			{
				(Biome)2,
				2
			},
			{
				(Biome)256,
				2
			},
			{
				(Biome)4,
				3
			},
			{
				(Biome)16,
				4
			},
			{
				(Biome)512,
				5
			},
			{
				(Biome)32,
				6
			},
			{
				(Biome)64,
				7
			}
		};

		private static readonly SortedDictionary<int, float>[] CreatureTables = new SortedDictionary<int, float>[5]
		{
			null,
			Table(37.5f, 17.5f, 7.5f, 2.5f, 0f),
			Table(45f, 25f, 12.5f, 5f, 1.25f, 0f),
			Table(55f, 32.5f, 17.5f, 7.5f, 2.5f, 0f),
			Table(66.25f, 41.25f, 23.75f, 11.25f, 3.75f, 0f)
		};

		private static readonly SortedDictionary<int, float>[] BossTables = new SortedDictionary<int, float>[3]
		{
			Table(35f, 15f, 5f, 0f),
			Table(43.75f, 23.75f, 11.25f, 3.75f, 0f),
			Table(52.5f, 32.5f, 17.5f, 7.5f, 2.5f, 0f)
		};

		private static readonly string[] StageNames = new string[5] { "base (3*)", "4*", "5*", "5* boost 1", "5* boost 2" };

		private static readonly float[] DamageFactors = new float[6] { 1f, 1.5f, 2f, 2.5f, 2.75f, 3f };

		private static ConfigEntry<bool> _progression;

		private static ConfigEntry<bool> _damage;

		private static ConfigEntry<bool> _bossTrophies;

		private static ConfigEntry<bool> _logTrophyRolls;

		private static ConfigEntry<bool> _logStars;

		private static ConfigEntry<float> _bossTrophyMultiplier;

		private static ConfigEntry<string> _trophyChances;

		private static float[] _trophyChanceTable;

		private static ManualLogSource _log;

		private static readonly FieldRef<Attack, Humanoid> AttackCharacter = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static ConfigEntry<float> _slsDamagePerStar;

		private static ConfigEntry<bool> _scaleAllLoot;

		[ThreadStatic]
		private static Character _rolling;

		private static int _loggedHighest = int.MinValue;

		[ThreadStatic]
		private static string _bossTableUsed;

		[ThreadStatic]
		private static string _creatureTableUsed;

		private static readonly Dictionary<string, int[]> CreatureRolls = new Dictionary<string, int[]>();

		private static float _nextSummary;

		private void Awake()
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			_progression = ((BaseUnityPlugin)this).Config.Bind<bool>("Stars", "Boss progression", true, "Bosses raise the star cap of earlier biomes (one boss behind, up to 5 stars, then two chance boosts) and of earlier bosses (two bosses behind). Off = only LevelSettings.yaml and MaxBossLevel apply.");
			_damage = ((BaseUnityPlugin)this).Config.Bind<bool>("Stars", "Per-star damage", true, "Normal creatures deal +50% damage per star up to 3 stars, +175% at 4 and +200% at 5 stars. Creatures in the Ocean get no extra damage from stars. Off = SLS's EnemyDamageLevelMultiplier for every star.");
			_logStars = ((BaseUnityPlugin)this).Config.Bind<bool>("Stars", "Log star progression", false, "Write the active star stage per biome and every boss level roll to the BepInEx log.");
			_trophyChances = ((BaseUnityPlugin)this).Config.Bind<string>("Trophies", "Trophy chance per star (%)", "10, 15, 20, 25, 37.5, 50", "Normal creatures: minimum trophy chance at 0, 1, 2, ... stars. Creatures with a higher vanilla chance keep theirs. Stars past the list use the last value.");
			_bossTrophies = ((BaseUnityPlugin)this).Config.Bind<bool>("Trophies", "Multiply boss trophies per star", true, "Starred bosses drop more trophies, on top of Epic Loot's one-per-player count.");
			_bossTrophyMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Trophies", "Boss trophy multiplier per star", 1.5f, new ConfigDescription("Boss trophies x this per star: 1.5 = x1, x1.5, x2.25, x3.4, x5.1, x7.6 at 0-5 stars (fractions rounded randomly).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f), Array.Empty<object>()));
			_logTrophyRolls = ((BaseUnityPlugin)this).Config.Bind<bool>("Trophies", "Log trophy rolls", false, "Write how each trophy drop was rolled to the BepInEx log.");
			_trophyChanceTable = ParseChances(_trophyChances.Value);
			_trophyChances.SettingChanged += delegate
			{
				_trophyChanceTable = ParseChances(_trophyChances.Value);
			};
			Type type = AccessTools.TypeByName("StarLevelSystem.common.ValConfig");
			_slsDamagePerStar = AccessTools.Field(type, "EnemyDamageLevelMultiplier")?.GetValue(null) as ConfigEntry<float>;
			_scaleAllLoot = AccessTools.Field(type, "ScaleAllLootByLevel")?.GetValue(null) as ConfigEntry<bool>;
			Harmony val = new Harmony("pieter.valheim.bossstarsafterdefeat");
			Type type2 = AccessTools.TypeByName("StarLevelSystem.modules.LevelSystem.LevelSelection");
			Type type3 = AccessTools.TypeByName("StarLevelSystem.modules.LevelSystem.ConditionalScaleSystem");
			MethodInfo methodInfo = AccessTools.Method(type2, "GetMaxCreatureLevel", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = type2?.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.Name == "DetermineLevel" && m.GetParameters().Length != 0 && m.GetParameters()[0].ParameterType == typeof(Character));
			MethodInfo methodInfo3 = type2?.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.Name == "DetermineLevelupChance" && m.GetParameters().Length == 6);
			MethodInfo methodInfo4 = AccessTools.Method(type3, "GetConditionalLevelupChance", (Type[])null, (Type[])null);
			if (methodInfo == null || methodInfo2 == null || methodInfo3 == null || methodInfo4 == null || _slsDamagePerStar == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)($"Star progression disabled, StarLevelSystem internals not found (max {methodInfo != null}, " + $"roll {methodInfo2 != null}, chance {methodInfo3 != null}, conditional {methodInfo4 != null}, " + $"damage {_slsDamagePerStar != null})."));
			}
			else
			{
				val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, Hook("MaxLevelPostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)methodInfo2, Hook("DeterminePrefix"), Hook("DeterminePostfix"), (HarmonyMethod)null, Hook("DetermineFinalizer"), (HarmonyMethod)null);
				val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, Hook("BossChancePostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, Hook("ConditionalChancePostfix"), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method(typeof(Attack), "GetLevelDamageFactor", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "DamageFactorPostfix", (Type[])null)
				{
					priority = 0
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			val.Patch((MethodBase)AccessTools.Method(typeof(CharacterDrop), "GenerateDropList", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "DropListPostfix", (Type[])null)
			{
				priority = 0
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Boss star progression, per-star damage and per-star trophies active.");
		}

		private static HarmonyMethod Hook(string name)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return new HarmonyMethod(typeof(Plugin).GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic));
		}

		private static SortedDictionary<int, float> Table(params float[] chances)
		{
			SortedDictionary<int, float> sortedDictionary = new SortedDictionary<int, float>();
			for (int i = 0; i < chances.Length; i++)
			{
				sortedDictionary[i + 1] = chances[i];
			}
			return sortedDictionary;
		}

		private static float[] ParseChances(string text)
		{
			List<float> list = new List<float>();
			string[] array = (text ?? "").Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				if (float.TryParse(array[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					list.Add(Mathf.Clamp(result, 0f, 100f));
				}
			}
			if (list.Count <= 0)
			{
				return new float[1];
			}
			return list.ToArray();
		}

		private static int HighestDefeated()
		{
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return -1;
			}
			for (int num = BossKeys.Length - 1; num >= 0; num--)
			{
				if (ZoneSystem.instance.GetGlobalKey(BossKeys[num]))
				{
					return num;
				}
			}
			return -1;
		}

		private static int BiomeStage(Biome biome, int highest)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!BiomeIndex.TryGetValue(biome, out var value))
			{
				return 0;
			}
			return Mathf.Clamp(highest - value, 0, CreatureTables.Length - 1);
		}

		private static int BossStage(Character boss, int highest)
		{
			int num = Array.IndexOf(BossKeys, boss.m_defeatSetGlobalKey);
			if (num >= 0)
			{
				return Mathf.Clamp(highest - num - 1, 0, BossTables.Length - 1);
			}
			return 0;
		}

		private static void ConditionalChancePostfix(Biome biome, ref SortedDictionary<int, float> __result)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (_progression.Value)
			{
				int highest = HighestDefeated();
				LogStages(highest);
				int num = BiomeStage(biome, highest);
				if (num > 0)
				{
					__result = CreatureTables[num];
				}
			}
		}

		private static void MaxLevelPostfix(Character character, ref int __result)
		{
			if (__result <= 1 || (Object)(object)character == (Object)null || !character.IsBoss())
			{
				return;
			}
			string defeatSetGlobalKey = character.m_defeatSetGlobalKey;
			if (!string.IsNullOrEmpty(defeatSetGlobalKey) && !((Object)(object)ZoneSystem.instance == (Object)null))
			{
				if (!ZoneSystem.instance.GetGlobalKey(defeatSetGlobalKey))
				{
					__result = 1;
				}
				else if (_progression.Value)
				{
					__result = BossTables[BossStage(character, HighestDefeated())].Keys.Last();
				}
			}
		}

		private static void DeterminePrefix(Character character)
		{
			_rolling = character;
			_bossTableUsed = null;
			_creatureTableUsed = null;
		}

		private static void DeterminePostfix(Character character, ZDO cZDO, Biome biome, int leveloverride, bool allowRoll, int __result)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (_logStars.Value && !((Object)(object)character == (Object)null) && _progression.Value)
			{
				if (!character.IsBoss())
				{
					RecordCreatureRoll(biome, cZDO, leveloverride, allowRoll, __result);
					return;
				}
				int num = BossStage(character, HighestDefeated());
				ManualLogSource log = _log;
				string[] obj = new string[5]
				{
					$"Star roll: boss {Utils.GetPrefabName(((Component)character).gameObject)} level {__result} ({Math.Max(0, __result - 1)}*), ",
					null,
					null,
					null,
					null
				};
				string arg = StageNames[num];
				ZoneSystem instance = ZoneSystem.instance;
				obj[1] = $"table {arg}, defeated before: {((instance != null) ? new bool?(instance.GetGlobalKey(character.m_defeatSetGlobalKey)) : ((bool?)null))}, ";
				obj[2] = $"saved level {((cZDO != null) ? new int?(cZDO.GetInt(ZDOVars.s_level, 0)) : ((int?)null))}, override {leveloverride}, roll allowed {allowRoll}, ";
				obj[3] = "boss table used: ";
				obj[4] = _bossTableUsed ?? "no (no new roll)";
				log.LogInfo((object)string.Concat(obj));
			}
		}

		private static Exception DetermineFinalizer(Exception __exception)
		{
			_rolling = null;
			return __exception;
		}

		private static void BossChancePostfix(bool isBoss, ref SortedDictionary<int, float> __result)
		{
			if (!isBoss)
			{
				int num = Array.IndexOf(CreatureTables, __result);
				_creatureTableUsed = ((num > 0) ? StageNames[num] : ((__result != null && __result.TryGetValue(1, out var value)) ? $"default (1+ stars {value}%)" : "none"));
			}
			else if (_progression.Value && !((Object)(object)_rolling == (Object)null) && _rolling.IsBoss())
			{
				int num2 = BossStage(_rolling, HighestDefeated());
				__result = BossTables[num2];
				_bossTableUsed = $"{StageNames[num2]} (1+ stars {__result[1]}%)";
			}
		}

		private static void RecordCreatureRoll(Biome biome, ZDO zdo, int leveloverride, bool allowRoll, int level)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (allowRoll && leveloverride <= 0 && zdo != null && zdo.GetInt(ZDOVars.s_level, 0) <= 0 && _creatureTableUsed != null)
			{
				string key = $"{biome} [{_creatureTableUsed}]";
				if (!CreatureRolls.TryGetValue(key, out var value))
				{
					value = (CreatureRolls[key] = new int[7]);
				}
				value[Mathf.Clamp(level - 1, 0, 6)]++;
			}
			_creatureTableUsed = null;
			if (Time.time < _nextSummary || CreatureRolls.Count == 0)
			{
				return;
			}
			_nextSummary = Time.time + 60f;
			foreach (KeyValuePair<string, int[]> pair in CreatureRolls)
			{
				int total = pair.Value.Sum();
				string arg = string.Join(", ", from i in Enumerable.Range(0, 7)
					where pair.Value[i] > 0
					select $"{i}* {pair.Value[i]} ({100f * (float)pair.Value[i] / (float)total:0}%)");
				_log.LogInfo((object)$"Star rolls: {pair.Key}: {total} new creatures: {arg}");
			}
			CreatureRolls.Clear();
		}

		private static void LogStages(int highest)
		{
			if (highest != _loggedHighest && _logStars.Value)
			{
				_loggedHighest = highest;
				Biome[] array = new Biome[9];
				RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				IEnumerable<string> values = ((IEnumerable<Biome>)(object)array).Select((Biome b) => $"{b} {StageNames[BiomeStage(b, highest)]}");
				_log.LogInfo((object)("Star stages (latest boss: " + ((highest >= 0) ? BossKeys[highest] : "none") + "): " + string.Join(", ", values)));
			}
		}

		private static void DamageFactorPostfix(Attack __instance, ref float __result)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			if (!_damage.Value || _slsDamagePerStar == null)
			{
				return;
			}
			Humanoid val = AttackCharacter.Invoke(__instance);
			if ((Object)(object)val == (Object)null || ((Character)val).IsPlayer() || ((Character)val).IsBoss())
			{
				return;
			}
			int num = ((Character)val).GetLevel() - 1;
			if (num > 0)
			{
				float num2 = 1f + (float)num * _slsDamagePerStar.Value;
				if (!(num2 <= 0f))
				{
					float num3 = (((int)Heightmap.FindBiome(((Component)val).transform.position) == 256) ? 1f : ((num < DamageFactors.Length) ? DamageFactors[num] : (DamageFactors[DamageFactors.Length - 1] + 0.25f * (float)(num - DamageFactors.Length + 1))));
					__result = __result / num2 * num3;
				}
			}
		}

		private static void DropListPostfix(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> __result)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Invalid comparison between Unknown and I4
			if (__result == null)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			int num = Mathf.Clamp(component.GetLevel() - 1, 0, 10);
			if (!component.IsBoss())
			{
				ExtraTrophyRoll(__instance, __result, num);
			}
			else
			{
				if (num == 0 || !_bossTrophies.Value)
				{
					return;
				}
				float num2 = Mathf.Pow(_bossTrophyMultiplier.Value, (float)num);
				for (int i = 0; i < __result.Count; i++)
				{
					ItemDrop obj = (Object.op_Implicit((Object)(object)__result[i].Key) ? __result[i].Key.GetComponent<ItemDrop>() : null);
					if (obj != null && (int)(obj.m_itemData?.m_shared?.m_itemType).GetValueOrDefault() == 13)
					{
						float num3 = (float)__result[i].Value * num2;
						int num4 = Mathf.FloorToInt(num3);
						if (Random.value < num3 - (float)num4)
						{
							num4++;
						}
						num4 = Mathf.Max(__result[i].Value, num4);
						LogRoll($"boss {Utils.GetPrefabName(((Component)__instance).gameObject)} {num}*: {((Object)__result[i].Key).name} {__result[i].Value} x {num2:0.##} = {num3:0.##} -> {num4}");
						__result[i] = new KeyValuePair<GameObject, int>(__result[i].Key, num4);
					}
				}
			}
		}

		private static void ExtraTrophyRoll(CharacterDrop drop, List<KeyValuePair<GameObject, int>> result, int stars)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Invalid comparison between Unknown and I4
			string text = $"{Utils.GetPrefabName(((Component)drop).gameObject)} {stars}*";
			float[] trophyChanceTable = _trophyChanceTable;
			float num = trophyChanceTable[Mathf.Min(stars, trophyChanceTable.Length - 1)] / 100f;
			if (drop.m_drops == null)
			{
				LogRoll(text + ": no drop table");
				return;
			}
			bool flag = false;
			foreach (Drop entry in drop.m_drops)
			{
				ItemDrop obj = (Object.op_Implicit((Object)(object)entry?.m_prefab) ? entry.m_prefab.GetComponent<ItemDrop>() : null);
				if (obj == null || (int)(obj.m_itemData?.m_shared?.m_itemType).GetValueOrDefault() != 13)
				{
					continue;
				}
				flag = true;
				string name = ((Object)entry.m_prefab).name;
				string text2 = $"{text}: {name} vanilla {entry.m_chance:P1}";
				int num2 = result.FindIndex((KeyValuePair<GameObject, int> r) => (Object)(object)r.Key == (Object)(object)entry.m_prefab);
				if (num2 >= 0)
				{
					LogRoll($"{text2} -> vanilla roll HIT, dropping {result[num2].Value}");
					continue;
				}
				if (entry.m_chance <= 0f || entry.m_chance >= 1f || num <= 0f)
				{
					LogRoll($"{text2} -> vanilla roll missed, no extra roll (chance {entry.m_chance:P1}, target {num:P1})");
					continue;
				}
				float num3 = Mathf.Min(1f, num);
				if (num3 <= entry.m_chance)
				{
					LogRoll($"{text2} -> vanilla roll missed, vanilla chance already >= target {num3:P1}");
					continue;
				}
				float num4 = (num3 - entry.m_chance) / (1f - entry.m_chance);
				float value = Random.value;
				if (value >= num4)
				{
					LogRoll($"{text2} -> vanilla missed, extra roll {value:0.000} vs {num4:0.000} (total {num3:P1}) MISSED");
					continue;
				}
				int num5 = Random.Range(entry.m_amountMin, entry.m_amountMax + 1);
				if (entry.m_levelMultiplier || (_scaleAllLoot != null && _scaleAllLoot.Value))
				{
					num5 *= stars + 1;
				}
				num5 = Mathf.Max(1, num5);
				result.Add(new KeyValuePair<GameObject, int>(entry.m_prefab, num5));
				LogRoll($"{text2} -> vanilla missed, extra roll {value:0.000} vs {num4:0.000} (total {num3:P1}) HIT, dropping {num5}");
			}
			if (!flag)
			{
				LogRoll(text + ": has no trophy in its drop table");
			}
		}

		private static void LogRoll(string message)
		{
			if (_logTrophyRolls.Value)
			{
				_log.LogInfo((object)("Trophy roll: " + message));
			}
		}
	}
}