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 ArenaCustomize v1.0.1
ArenaCustomize.dll
Decompiled 3 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("zabu")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabumod")] [assembly: AssemblyTitle("zabumod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPOJP.ArenaCustomize { [BepInPlugin("REPOJP.ArenaCustomize", "ArenaCustomize", "1.4.0")] public sealed class ArenaCustomizePlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Arena), "ArenaInitMultiplayer")] private static class Arena_ArenaInitMultiplayer_Patch { private static bool Prefix(Arena __instance) { if (!CfgEnableMod.Value) { return true; } try { RunArenaInit(__instance); return false; } catch (Exception ex) { Log.LogError((object)("Failure: ArenaInitMultiplayer Prefix\n" + ex)); return true; } } } [HarmonyPatch(typeof(Arena), "SpawnMidWeapons")] private static class Arena_SpawnMidWeapons_Patch { private static bool Prefix() { if (!CfgEnableMod.Value || !SemiFunc.RunIsArena()) { return true; } if (CfgDisableMidWeaponSpawn.Value) { return false; } return true; } } [HarmonyPatch(typeof(Arena), "StateLevel1")] private static class Arena_StateLevel1_Patch { private static bool Prefix(Arena __instance) { return HandleArenaTimedState(__instance, CfgLevel1Seconds.Value, isLevel3: false); } } [HarmonyPatch(typeof(Arena), "StateLevel2")] private static class Arena_StateLevel2_Patch { private static bool Prefix(Arena __instance) { return HandleArenaTimedState(__instance, CfgLevel2Seconds.Value, isLevel3: false); } } [HarmonyPatch(typeof(Arena), "StateLevel3")] private static class Arena_StateLevel3_Patch { private static bool Prefix(Arena __instance) { return HandleArenaTimedState(__instance, CfgLevel3Seconds.Value, isLevel3: true); } } [HarmonyPatch(typeof(Arena), "StatePlatformRemove")] private static class Arena_StatePlatformRemove_Patch { private static bool Prefix(Arena __instance) { return HandlePlatformRemove(__instance); } } public const string PluginGuid = "REPOJP.ArenaCustomize"; public const string PluginName = "ArenaCustomize"; public const string PluginVersion = "1.4.0"; internal static ArenaCustomizePlugin Instance; internal static ManualLogSource Log; private Harmony harmony; private float periodicBatteryRefillTimer; private const string SectionGeneral = "A General"; private const string SectionPlatformTimer = "B Platform Timer"; private const string SectionPlatformRemove = "D Platform Remove"; private const string SectionItemCountsMelee = "E Item Counts - Melee"; private const string SectionItemCountsGuns = "F Item Counts - Guns"; private const string SectionItemCountsCarts = "G Item Counts - Carts"; private const string SectionItemCountsDrones = "H Item Counts - Drones"; private const string SectionItemCountsOrbs = "I Item Counts - Orbs"; private const string SectionItemCountsHealth = "J Item Counts - Health"; private const string SectionItemCountsUsables = "K Item Counts - Usables"; internal static ConfigEntry<bool> CfgEnableMod; internal static ConfigEntry<bool> CfgDisableMidWeaponSpawn; internal static ConfigEntry<bool> CfgEnableArenaItemSpawn; internal static ConfigEntry<bool> CfgEnablePeriodicBatteryRefillInArena; internal static ConfigEntry<int> CfgPeriodicBatteryRefillIntervalSeconds; internal static ConfigEntry<bool> CfgWriteSpawnLog; internal static ConfigEntry<bool> CfgShuffleItemVolumes; internal static ConfigEntry<bool> CfgSpawnOverflowAtCenter; internal static ConfigEntry<float> CfgSpawnOverflowRadius; internal static ConfigEntry<float> CfgSpawnOverflowHeightStep; internal static ConfigEntry<int> CfgLevel1Seconds; internal static ConfigEntry<int> CfgLevel2Seconds; internal static ConfigEntry<int> CfgLevel3Seconds; internal static ConfigEntry<bool> CfgKeepLastPlatform; internal static ConfigEntry<float> CfgPlatformRemoveDurationSeconds; internal static ConfigEntry<bool> CfgEnablePlatformShrink; private static readonly Dictionary<string, Item> ItemByKey = new Dictionary<string, Item>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, ConfigEntry<int>> ItemCountConfigsByKey = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, List<string>> SectionToItemKeys = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, int> DefaultSpawnCounts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) { { "BaseballBat", 2 }, { "FryingPan", 2 }, { "InflatableHammer", 2 }, { "Prodzap", 2 }, { "SledgeHammer", 2 }, { "Sword", 2 }, { "Boltzap", 1 }, { "CARTCannon", 1 }, { "CARTLaser", 1 }, { "Gun", 1 }, { "PhotonBlaster", 1 }, { "PulsePistol", 1 }, { "Shotgun", 1 }, { "TranqGun", 1 }, { "CART", 1 }, { "POCKETCART", 0 }, { "FeatherDrone", 0 }, { "HealerDrone", 0 }, { "IndestructibleDrone", 0 }, { "RechargeDrone", 0 }, { "RollDrone", 0 }, { "ZeroGravityDrone", 0 }, { "FeatherOrb", 1 }, { "HealerOrb", 1 }, { "IndestructibleOrb", 1 }, { "MagnetOrb", 1 }, { "RechargeOrb", 1 }, { "RollOrb", 1 }, { "ZeroGravityOrb", 0 }, { "LargeHealthPack100", 2 }, { "MediumHealthPack50", 2 }, { "SmallHealthPack25", 2 }, { "CrouchRestUpgrade", 3 }, { "DeathHeadBatteryUpgrade", 0 }, { "DuckBucket", 0 }, { "DuctTapedGrenades", 3 }, { "EnergyCrystal", 0 }, { "ExplosiveMine", 0 }, { "ExtraJumpUpgrade", 3 }, { "ExtractionTracker", 0 }, { "Grenade", 0 }, { "HealthUpgrade", 3 }, { "HumanGrenade", 0 }, { "MapPlayerCountUpgrade", 0 }, { "PhaseBridge", 1 }, { "RangeUpgrade", 3 }, { "RubberDuck", 0 }, { "ShockwaveGrenade", 0 }, { "ShockwaveMine", 0 }, { "SprintSpeedUpgrade", 3 }, { "StaminaUpgrade", 3 }, { "StrengthUpgrade", 3 }, { "StunGrenade", 0 }, { "Trapzap", 0 }, { "TumbleClimbUpgrade", 3 }, { "TumbleLaunchUpgrade", 3 }, { "TumbleWingsUpgrade", 3 }, { "ValuableTracker", 0 } }; private static readonly FieldInfo ArenaFieldStateStart = AccessTools.Field(typeof(Arena), "stateStart"); private static readonly FieldInfo ArenaFieldStateTimer = AccessTools.Field(typeof(Arena), "stateTimer"); private static readonly FieldInfo ArenaFieldLevel = AccessTools.Field(typeof(Arena), "level"); private static readonly FieldInfo ArenaFieldFinalPlatform = AccessTools.Field(typeof(Arena), "finalPlatform"); private static readonly FieldInfo ArenaFieldNextLevel = AccessTools.Field(typeof(Arena), "nextLevel"); private static readonly FieldInfo ArenaFieldPlatforms = AccessTools.Field(typeof(Arena), "platforms"); private static readonly FieldInfo ArenaFieldItemsMid = AccessTools.Field(typeof(Arena), "itemsMid"); private static readonly MethodInfo ArenaMethodNextLevel = AccessTools.Method(typeof(Arena), "NextLevel", (Type[])null, (Type[])null); private static readonly MethodInfo PunManagerMethodSpawnItem = AccessTools.Method(typeof(PunManager), "SpawnItem", new Type[2] { typeof(Item), typeof(ItemVolume) }, (Type[])null); private static readonly MethodInfo ItemBatteryMethodBatteryFullPercentChange = AccessTools.Method(typeof(ItemBattery), "BatteryFullPercentChange", new Type[2] { typeof(int), typeof(bool) }, (Type[])null); private static readonly FieldInfo ItemBatteryFieldBatteryLife = AccessTools.Field(typeof(ItemBattery), "batteryLife"); private static readonly FieldInfo ItemBatteryFieldBatteryBars = AccessTools.Field(typeof(ItemBattery), "batteryBars"); private static readonly FieldInfo ItemBatteryFieldBatteryLifeInt = AccessTools.Field(typeof(ItemBattery), "batteryLifeInt"); private static readonly FieldInfo ItemBatteryFieldBatteryLifeCountBars = AccessTools.Field(typeof(ItemBattery), "batteryLifeCountBars"); private static readonly FieldInfo ItemBatteryFieldBatteryLifeCountBarsPrev = AccessTools.Field(typeof(ItemBattery), "batteryLifeCountBarsPrev"); private static readonly FieldInfo ItemBatteryFieldDrainRate = AccessTools.Field(typeof(ItemBattery), "drainRate"); private static readonly FieldInfo ItemBatteryFieldDrainTimer = AccessTools.Field(typeof(ItemBattery), "drainTimer"); private static readonly FieldInfo ItemBatteryFieldChargeRate = AccessTools.Field(typeof(ItemBattery), "chargeRate"); private static readonly FieldInfo ItemBatteryFieldChargeTimer = AccessTools.Field(typeof(ItemBattery), "chargeTimer"); private void Awake() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown try { Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); InitializeSectionLists(); BindGeneralConfig(); BindPlatformConfig(); BuildAllItemConfigsAtAwake(); periodicBatteryRefillTimer = Mathf.Max(1, CfgPeriodicBatteryRefillIntervalSeconds.Value); harmony = new Harmony("REPOJP.ArenaCustomize"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ArenaCustomize loaded"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex)); } } private void Update() { try { if (!CfgEnableMod.Value || !CfgEnablePeriodicBatteryRefillInArena.Value) { return; } if (!SemiFunc.RunIsArena()) { periodicBatteryRefillTimer = Mathf.Max(1, CfgPeriodicBatteryRefillIntervalSeconds.Value); } else if (SemiFunc.IsMasterClientOrSingleplayer()) { periodicBatteryRefillTimer -= Time.deltaTime; if (!(periodicBatteryRefillTimer > 0f)) { periodicBatteryRefillTimer = Mathf.Max(1, CfgPeriodicBatteryRefillIntervalSeconds.Value); RefillAllArenaItemBatteries(); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Update\n" + ex)); } } private void OnDestroy() { try { if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: OnDestroy\n" + ex)); } } private static void InitializeSectionLists() { SectionToItemKeys.Clear(); SectionToItemKeys["E Item Counts - Melee"] = new List<string>(); SectionToItemKeys["F Item Counts - Guns"] = new List<string>(); SectionToItemKeys["G Item Counts - Carts"] = new List<string>(); SectionToItemKeys["H Item Counts - Drones"] = new List<string>(); SectionToItemKeys["I Item Counts - Orbs"] = new List<string>(); SectionToItemKeys["J Item Counts - Health"] = new List<string>(); SectionToItemKeys["K Item Counts - Usables"] = new List<string>(); } private void BindGeneralConfig() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown CfgEnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnableMod", true, "Enable or disable this mod.このMODの有効無効"); CfgDisableMidWeaponSpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "DisableMidWeaponSpawn", false, "Disable arena mid weapon spawn completely.arena中央途中武器スポーン完全無効"); CfgEnableArenaItemSpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnableArenaItemSpawn", true, "Enable arena item spawning.arena内アイテム生成有効"); CfgEnablePeriodicBatteryRefillInArena = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnablePeriodicBatteryRefillInArena", true, "Periodically refill all item batteries only in arena.arena内のみ全アイテムの充電を定期満タン化"); CfgPeriodicBatteryRefillIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("A General", "PeriodicBatteryRefillIntervalSeconds", 10, new ConfigDescription("How often to refill all item batteries in arena.seconds.arena内で全アイテムの充電を満タンにする間隔秒", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); CfgWriteSpawnLog = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "WriteSpawnLog", true, "Write detailed spawn and classification logs.詳細な生成と分類ログ出力"); CfgShuffleItemVolumes = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "ShuffleItemVolumes", true, "Shuffle arena item volumes before matching.生成前にarenaのItemVolume順をシャッフル"); CfgSpawnOverflowAtCenter = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "SpawnOverflowAtCenter", true, "Spawn overflow items around arena center when matching volumes are exhausted.一致するItemVolume不足時にarena中央周辺へ追加生成"); CfgSpawnOverflowRadius = ((BaseUnityPlugin)this).Config.Bind<float>("A General", "SpawnOverflowRadius", 2f, new ConfigDescription("Overflow spawn radius around center.中央追加生成半径", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); CfgSpawnOverflowHeightStep = ((BaseUnityPlugin)this).Config.Bind<float>("A General", "SpawnOverflowHeightStep", 0.25f, new ConfigDescription("Overflow spawn height step.中央追加生成の高さ差", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); } private void BindPlatformConfig() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown CfgLevel1Seconds = ((BaseUnityPlugin)this).Config.Bind<int>("B Platform Timer", "Level1Seconds", 30, new ConfigDescription("Arena level 1 duration seconds.arenaレベル1時間", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 180), Array.Empty<object>())); CfgLevel2Seconds = ((BaseUnityPlugin)this).Config.Bind<int>("B Platform Timer", "Level2Seconds", 30, new ConfigDescription("Arena level 2 duration seconds.arenaレベル2時間", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 180), Array.Empty<object>())); CfgLevel3Seconds = ((BaseUnityPlugin)this).Config.Bind<int>("B Platform Timer", "Level3Seconds", 30, new ConfigDescription("Arena level 3 duration seconds.arenaレベル3時間", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 180), Array.Empty<object>())); CfgKeepLastPlatform = ((BaseUnityPlugin)this).Config.Bind<bool>("B Platform Timer", "KeepLastPlatform", true, "Keep the final platform instead of dropping it.最後の床を落とさない"); CfgPlatformRemoveDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("D Platform Remove", "PlatformRemoveDurationSeconds", 3f, new ConfigDescription("Platform remove phase duration seconds.床落下フェーズ時間", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>())); CfgEnablePlatformShrink = ((BaseUnityPlugin)this).Config.Bind<bool>("D Platform Remove", "EnablePlatformShrink", true, "Actually drop platforms after warning.警告後に実際に床を落とす"); } private static void BuildAllItemConfigsAtAwake() { try { ItemByKey.Clear(); InitializeSectionLists(); List<Item> list = CollectAllItemsFromResources(); Dictionary<string, int> usedConfigKeys = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < list.Count; i++) { RegisterCatalogItem(list[i], usedConfigKeys); } SortSectionItemLists(); } catch (Exception ex) { Log.LogError((object)("Failure: BuildAllItemConfigsAtAwake\n" + ex)); } } private static List<Item> CollectAllItemsFromResources() { Dictionary<string, Item> dictionary = new Dictionary<string, Item>(StringComparer.OrdinalIgnoreCase); try { Item[] array = Resources.LoadAll<Item>(string.Empty); for (int i = 0; i < array.Length; i++) { RegisterItemToMap(dictionary, array[i]); } } catch (Exception ex) { Log.LogError((object)("Failure: Resources.LoadAll<Item>\n" + ex)); } try { Item[] array2 = Resources.FindObjectsOfTypeAll<Item>(); for (int j = 0; j < array2.Length; j++) { RegisterItemToMap(dictionary, array2[j]); } } catch (Exception ex2) { Log.LogError((object)("Failure: Resources.FindObjectsOfTypeAll<Item>\n" + ex2)); } List<Item> list = new List<Item>(dictionary.Values); list.Sort(CompareItemsForConfig); return list; } private static void RegisterItemToMap(Dictionary<string, Item> map, Item item) { if (!((Object)(object)item == (Object)null)) { string uniqueItemKey = GetUniqueItemKey(item); if (!string.IsNullOrEmpty(uniqueItemKey) && !map.ContainsKey(uniqueItemKey)) { map.Add(uniqueItemKey, item); } } } private static int CompareItemsForConfig(Item a, Item b) { string strA = ResolveConfigSection(a) + "|" + GetItemDisplayName(a) + "|" + ((Object)a).name; string strB = ResolveConfigSection(b) + "|" + GetItemDisplayName(b) + "|" + ((Object)b).name; return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase); } private static void RegisterCatalogItem(Item item, Dictionary<string, int> usedConfigKeys) { //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown if ((Object)(object)item == (Object)null) { return; } string text = ResolveConfigSection(item); if (string.IsNullOrEmpty(text)) { return; } string uniqueItemKey = GetUniqueItemKey(item); if (string.IsNullOrEmpty(uniqueItemKey)) { return; } if (!ItemByKey.ContainsKey(uniqueItemKey)) { ItemByKey.Add(uniqueItemKey, item); } if (!SectionToItemKeys.TryGetValue(text, out List<string> value)) { value = new List<string>(); SectionToItemKeys[text] = value; } if (!value.Contains(uniqueItemKey)) { value.Add(uniqueItemKey); } if (!ItemCountConfigsByKey.ContainsKey(uniqueItemKey)) { string itemDisplayName = GetItemDisplayName(item); string text2 = SanitizeConfigKey(itemDisplayName); if (string.IsNullOrEmpty(text2)) { text2 = SanitizeConfigKey(((Object)item).name); } if (string.IsNullOrEmpty(text2)) { text2 = "UnknownItem"; } string text3 = BuildUniqueConfigKey(text2, usedConfigKeys) + "Count"; int defaultSpawnCount = GetDefaultSpawnCount(item, text2); ConfigEntry<int> value2 = ((BaseUnityPlugin)Instance).Config.Bind<int>(text, text3, defaultSpawnCount, new ConfigDescription("Requested spawn count for " + itemDisplayName + "." + itemDisplayName + " の生成数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); ItemCountConfigsByKey[uniqueItemKey] = value2; if (CfgWriteSpawnLog != null && CfgWriteSpawnLog.Value) { Log.LogInfo((object)("Arena item classify: " + text + " -> " + itemDisplayName + " / unityName=" + ((Object)item).name + " / type=" + ((object)(itemType)(ref item.itemType)).ToString() + " / volume=" + ((object)(itemVolume)(ref item.itemVolume)).ToString() + " / path=" + GetPrefabResourcePath(item) + " / default=" + defaultSpawnCount)); } } } private static int GetDefaultSpawnCount(Item item, string sanitizedDisplayName) { if (!string.IsNullOrEmpty(sanitizedDisplayName) && DefaultSpawnCounts.TryGetValue(sanitizedDisplayName, out var value)) { return Mathf.Clamp(value, 0, 20); } string text = SanitizeConfigKey(((Object)(object)item != (Object)null) ? ((Object)item).name : string.Empty); if (!string.IsNullOrEmpty(text) && DefaultSpawnCounts.TryGetValue(text, out value)) { return Mathf.Clamp(value, 0, 20); } string prefabResourcePath = GetPrefabResourcePath(item); string text2 = SanitizeConfigKey(prefabResourcePath); if (!string.IsNullOrEmpty(text2) && DefaultSpawnCounts.TryGetValue(text2, out value)) { return Mathf.Clamp(value, 0, 20); } return 0; } private static void SortSectionItemLists() { foreach (KeyValuePair<string, List<string>> sectionToItemKey in SectionToItemKeys) { sectionToItemKey.Value.Sort(delegate(string a, string b) { Item value; string strA = (ItemByKey.TryGetValue(a, out value) ? GetItemDisplayName(value) : a); Item value2; string strB = (ItemByKey.TryGetValue(b, out value2) ? GetItemDisplayName(value2) : b); return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase); }); } } private static string BuildUniqueConfigKey(string baseKey, Dictionary<string, int> usedConfigKeys) { if (!usedConfigKeys.TryGetValue(baseKey, out var value)) { usedConfigKeys[baseKey] = 1; return baseKey; } return baseKey + "_" + (usedConfigKeys[baseKey] = value + 1); } private static string ResolveConfigSection(Item item) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Invalid comparison between Unknown and I4 //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Invalid comparison between Unknown and I4 //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Invalid comparison between Unknown and I4 //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Invalid comparison between Unknown and I4 //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Invalid comparison between Unknown and I4 //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Invalid comparison between Unknown and I4 //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Invalid comparison between Unknown and I4 //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Invalid comparison between Unknown and I4 //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Invalid comparison between Unknown and I4 //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Invalid comparison between Unknown and I4 if ((Object)(object)item == (Object)null) { return null; } string text = (GetItemDisplayName(item) + " " + ((Object)item).name + " " + GetPrefabResourcePath(item)).ToLowerInvariant(); itemType itemType = item.itemType; if ((int)itemType == 7 || text.Contains("baseball bat")) { return "E Item Counts - Melee"; } if ((int)itemType == 9 || text.Contains("handgun") || text.Contains("shotgun")) { return "F Item Counts - Guns"; } if ((int)itemType == 2 || (int)itemType == 12 || text.Contains("cart")) { return "G Item Counts - Carts"; } if ((int)itemType == 0 || text.Contains("drone")) { return "H Item Counts - Drones"; } if ((int)itemType == 1 || text.Contains("orb")) { return "I Item Counts - Orbs"; } if ((int)itemType == 8) { return "J Item Counts - Health"; } if ((int)itemType == 6 || (int)itemType == 10 || (int)itemType == 11 || (int)itemType == 13 || (int)itemType == 5 || (int)itemType == 3 || (int)itemType == 4) { return "K Item Counts - Usables"; } return null; } private static string GetUniqueItemKey(Item item) { if ((Object)(object)item == (Object)null) { return string.Empty; } string prefabResourcePath = GetPrefabResourcePath(item); if (!string.IsNullOrEmpty(prefabResourcePath)) { return prefabResourcePath; } if (!string.IsNullOrEmpty(((Object)item).name)) { return ((Object)item).name; } if (!string.IsNullOrEmpty(item.itemName)) { return item.itemName; } return string.Empty; } internal static string GetItemDisplayName(Item item) { if ((Object)(object)item == (Object)null) { return "Unknown"; } if (!string.IsNullOrEmpty(item.itemName)) { return item.itemName; } if (!string.IsNullOrEmpty(((Object)item).name)) { return ((Object)item).name; } return "Unknown"; } private static string GetPrefabResourcePath(Item item) { try { if ((Object)(object)item != (Object)null && item.prefab != null && !string.IsNullOrEmpty(item.prefab.ResourcePath)) { return item.prefab.ResourcePath; } } catch { } return string.Empty; } private static string SanitizeConfigKey(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(value.Length); foreach (char c in value) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString(); } internal static bool IsArenaActive() { return CfgEnableMod != null && CfgEnableMod.Value && SemiFunc.RunIsArena(); } internal static float NormalizeLevelSeconds(int value) { if (value < 0) { return -1f; } if (value > 180) { return 180f; } return value; } internal static float NormalizeNonNegativeSeconds(float value, float max) { if (value < 0f) { return 0f; } if (value > max) { return max; } return value; } internal static int GetConfiguredCount(Item item) { if ((Object)(object)item == (Object)null) { return 0; } string uniqueItemKey = GetUniqueItemKey(item); if (ItemCountConfigsByKey.TryGetValue(uniqueItemKey, out ConfigEntry<int> value)) { return Mathf.Clamp(value.Value, 0, 20); } return 0; } private static List<ItemVolume> CollectArenaVolumes(Arena arena) { List<ItemVolume> list = new List<ItemVolume>(); if ((Object)(object)arena == (Object)null || (Object)(object)arena.itemVolumes == (Object)null) { return list; } for (int i = 0; i < arena.itemVolumes.childCount; i++) { Transform child = arena.itemVolumes.GetChild(i); if (!((Object)(object)child == (Object)null)) { ItemVolume component = ((Component)child).GetComponent<ItemVolume>(); if ((Object)(object)component != (Object)null) { list.Add(component); } } } if (CfgShuffleItemVolumes.Value) { Shuffle(list); } return list; } private static void Shuffle<T>(IList<T> list) { if (list != null) { for (int num = list.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); T value = list[num]; list[num] = list[index]; list[index] = value; } } } internal static void RunArenaInit(Arena arena) { if ((Object)(object)arena == (Object)null || !CfgEnableMod.Value || !SemiFunc.IsMasterClientOrSingleplayer()) { return; } try { if (CfgWriteSpawnLog.Value) { Log.LogInfo((object)"Arena initial spawn start"); } ItemManager.instance.ResetAllItems(); ItemManager.instance.spawnedItems.Clear(); ItemManager.instance.purchasedItems.Clear(); List<Item> list = new List<Item>(); AddSectionItemsToList("E Item Counts - Melee", list); AddSectionItemsToList("F Item Counts - Guns", list); if (ArenaFieldItemsMid != null) { ArenaFieldItemsMid.SetValue(arena, list); } List<ItemVolume> list2 = CollectArenaVolumes(arena); if (CfgEnableArenaItemSpawn.Value) { SpawnConfiguredSection(arena, list2, "K Item Counts - Usables"); SpawnConfiguredSection(arena, list2, "E Item Counts - Melee"); SpawnConfiguredSection(arena, list2, "F Item Counts - Guns"); SpawnConfiguredSection(arena, list2, "G Item Counts - Carts"); SpawnConfiguredSection(arena, list2, "H Item Counts - Drones"); SpawnConfiguredSection(arena, list2, "I Item Counts - Orbs"); SpawnConfiguredSection(arena, list2, "J Item Counts - Health"); } else if (CfgWriteSpawnLog.Value) { Log.LogInfo((object)"Arena item spawn disabled by config"); } for (int i = 0; i < list2.Count; i++) { if ((Object)(object)list2[i] != (Object)null) { Object.Destroy((Object)(object)((Component)list2[i]).gameObject); } } } catch (Exception ex) { Log.LogError((object)("Failure: RunArenaInit\n" + ex)); } } private static void AddSectionItemsToList(string section, List<Item> target) { if (!SectionToItemKeys.TryGetValue(section, out List<string> value) || target == null) { return; } for (int i = 0; i < value.Count; i++) { if (ItemByKey.TryGetValue(value[i], out Item value2) && (Object)(object)value2 != (Object)null) { target.Add(value2); } } } private static void SpawnConfiguredSection(Arena arena, List<ItemVolume> availableVolumes, string sectionName) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00ef: Unknown result type (might be due to invalid IL or missing references) if (!SectionToItemKeys.TryGetValue(sectionName, out List<string> value) || value == null) { return; } for (int i = 0; i < value.Count; i++) { string key = value[i]; if (!ItemByKey.TryGetValue(key, out Item value2) || (Object)(object)value2 == (Object)null) { continue; } int configuredCount = GetConfiguredCount(value2); int num = 0; int num2 = 0; if (configuredCount > 0) { for (int j = 0; j < configuredCount; j++) { ItemVolume val = TakeMatchingVolume(availableVolumes, value2.itemVolume); if ((Object)(object)val != (Object)null) { if (SpawnUsingVanillaOrFallback(value2, ((Component)val).transform.position, ((Component)val).transform.rotation, val)) { num++; } } else if (CfgSpawnOverflowAtCenter.Value) { BuildOverflowTransform(arena, j, out var position, out var rotation); if (SpawnUsingVanillaOrFallback(value2, position, rotation, null)) { num2++; } } } } if (CfgWriteSpawnLog.Value) { Log.LogInfo((object)("Arena initial spawn request: " + sectionName + " -> " + GetItemDisplayName(value2) + " requested=" + configuredCount + " spawned=" + (num + num2) + " volume=" + num + " overflow=" + num2)); } } } private static ItemVolume TakeMatchingVolume(List<ItemVolume> availableVolumes, itemVolume itemVolume) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (availableVolumes == null) { return null; } for (int i = 0; i < availableVolumes.Count; i++) { ItemVolume val = availableVolumes[i]; if ((Object)(object)val != (Object)null && val.itemVolume == itemVolume) { availableVolumes.RemoveAt(i); return val; } } return null; } private static void BuildOverflowTransform(Arena arena, int spawnIndex, out Vector3 position, out Quaternion rotation) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0096: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)arena.itemsMidSpawner != (Object)null) ? arena.itemsMidSpawner : ((Component)arena).transform); Vector3 position2 = val.position; float num = Mathf.Max(0f, CfgSpawnOverflowRadius.Value); float num2 = Mathf.Max(0f, CfgSpawnOverflowHeightStep.Value); float num3 = (float)spawnIndex * 47.5f % 360f; float num4 = num3 * (MathF.PI / 180f); float num5 = 1f + Mathf.Floor((float)spawnIndex / 8f); float num6 = num * num5; position = new Vector3(position2.x + Mathf.Cos(num4) * num6, position2.y + num2 * (float)(spawnIndex % 4), position2.z + Mathf.Sin(num4) * num6); rotation = Quaternion.Euler(0f, num3, 0f); } private static bool SpawnUsingVanillaOrFallback(Item item, Vector3 position, Quaternion rotation, ItemVolume volumeOrNull) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0039: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) ItemVolume val = volumeOrNull; GameObject val2 = null; try { if ((Object)(object)item == (Object)null) { return false; } if ((Object)(object)val == (Object)null) { val2 = new GameObject("ArenaCustomize_TempItemVolume"); val2.transform.position = position; val2.transform.rotation = rotation; val = val2.AddComponent<ItemVolume>(); val.itemVolume = item.itemVolume; } if ((Object)(object)PunManager.instance != (Object)null && PunManagerMethodSpawnItem != null) { PunManagerMethodSpawnItem.Invoke(PunManager.instance, new object[2] { item, val }); return true; } Quaternion val3 = ((Component)val).transform.rotation * item.spawnRotationOffset; if (SemiFunc.IsMultiplayer()) { PhotonNetwork.InstantiateRoomObject(item.prefab.ResourcePath, ((Component)val).transform.position, val3, (byte)0, (object[])null); } else { Object.Instantiate<GameObject>(item.prefab.Prefab, ((Component)val).transform.position, val3); } return true; } catch (Exception ex) { Log.LogError((object)("Failure: SpawnUsingVanillaOrFallback " + GetItemDisplayName(item) + "\n" + ex)); return false; } finally { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } } internal static bool HandleArenaTimedState(Arena arena, int configuredSeconds, bool isLevel3) { if ((Object)(object)arena == (Object)null || !CfgEnableMod.Value || !SemiFunc.RunIsArena() || !SemiFunc.IsMasterClientOrSingleplayer()) { return true; } try { if (ArenaFieldStateStart != null && (bool)ArenaFieldStateStart.GetValue(arena)) { ArenaFieldStateStart.SetValue(arena, false); ArenaFieldStateTimer.SetValue(arena, NormalizeLevelSeconds(configuredSeconds)); } float num = NormalizeLevelSeconds(configuredSeconds); if (num < 0f) { return false; } float num2 = ((ArenaFieldStateTimer != null) ? ((float)ArenaFieldStateTimer.GetValue(arena)) : 0f); if (num2 <= 0f) { if (isLevel3 && CfgKeepLastPlatform.Value) { if (ArenaFieldStateTimer != null) { ArenaFieldStateTimer.SetValue(arena, -1f); } return false; } if (isLevel3 && ArenaFieldFinalPlatform != null) { ArenaFieldFinalPlatform.SetValue(arena, true); } if (ArenaMethodNextLevel != null) { ArenaMethodNextLevel.Invoke(arena, null); } } } catch (Exception ex) { Log.LogError((object)("Failure: HandleArenaTimedState\n" + ex)); } return false; } internal static bool HandlePlatformRemove(Arena arena) { //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)arena == (Object)null || !CfgEnableMod.Value || !SemiFunc.RunIsArena() || !SemiFunc.IsMasterClientOrSingleplayer()) { return true; } try { if (ArenaFieldStateStart != null && (bool)ArenaFieldStateStart.GetValue(arena)) { int num = ((ArenaFieldLevel != null) ? ((int)ArenaFieldLevel.GetValue(arena)) : 0); bool flag = ArenaFieldFinalPlatform != null && (bool)ArenaFieldFinalPlatform.GetValue(arena); List<ArenaPlatform> list = ((ArenaFieldPlatforms != null) ? (ArenaFieldPlatforms.GetValue(arena) as List<ArenaPlatform>) : null); if ((list == null || list.Count == 0) && (Object)(object)arena != (Object)null) { list = new List<ArenaPlatform>(((Component)arena).GetComponentsInChildren<ArenaPlatform>(true)); if (ArenaFieldPlatforms != null) { ArenaFieldPlatforms.SetValue(arena, list); } } if (CfgEnablePlatformShrink.Value && !(CfgKeepLastPlatform.Value && flag)) { int num2 = num - 1; if (list != null && num2 >= 0 && num2 < list.Count && (Object)(object)list[num2] != (Object)null) { list[num2].StateSet((States)2); } } if (arena.soundArenaRemove != null) { arena.soundArenaRemove.Play(((Component)arena).transform.position, 1f, 1f, 1f, 1f); } if ((Object)(object)GameDirector.instance != (Object)null) { GameDirector.instance.CameraShake.Shake(8f, 0.5f); GameDirector.instance.CameraImpact.Shake(8f, 0.1f); } if (ArenaFieldStateStart != null) { ArenaFieldStateStart.SetValue(arena, false); } if (ArenaFieldStateTimer != null) { ArenaFieldStateTimer.SetValue(arena, NormalizeNonNegativeSeconds(CfgPlatformRemoveDurationSeconds.Value, 120f)); } } float num3 = ((ArenaFieldStateTimer != null) ? ((float)ArenaFieldStateTimer.GetValue(arena)) : 0f); bool flag2 = ArenaFieldFinalPlatform != null && (bool)ArenaFieldFinalPlatform.GetValue(arena); if (num3 <= 0f && !flag2) { States val = (States)((!(ArenaFieldNextLevel != null)) ? 1 : ((int)(States)ArenaFieldNextLevel.GetValue(arena))); arena.StateSet(val); } } catch (Exception ex) { Log.LogError((object)("Failure: HandlePlatformRemove\n" + ex)); } return false; } private static bool IsBatteryAlreadyFull(ItemBattery battery) { if ((Object)(object)battery == (Object)null) { return true; } try { int batteryBarsValue = GetBatteryBarsValue(battery); int batteryLifeIntValue = GetBatteryLifeIntValue(battery); float batteryLifeValue = GetBatteryLifeValue(battery); return batteryLifeValue >= 99.9f && batteryLifeIntValue >= batteryBarsValue; } catch { return false; } } private static int GetBatteryBarsValue(ItemBattery battery) { if ((Object)(object)battery == (Object)null) { return 6; } try { if (ItemBatteryFieldBatteryBars != null) { object value = ItemBatteryFieldBatteryBars.GetValue(battery); if (value is int) { int num = (int)value; if (num > 0) { return num; } } } } catch { } return Mathf.Max(1, battery.batteryBars); } private static int GetBatteryLifeIntValue(ItemBattery battery) { if ((Object)(object)battery == (Object)null) { return 0; } try { if (ItemBatteryFieldBatteryLifeInt != null) { object value = ItemBatteryFieldBatteryLifeInt.GetValue(battery); if (value is int) { return (int)value; } } } catch { } return 0; } private static float GetBatteryLifeValue(ItemBattery battery) { if ((Object)(object)battery == (Object)null) { return 0f; } try { if (ItemBatteryFieldBatteryLife != null) { object value = ItemBatteryFieldBatteryLife.GetValue(battery); if (value is float) { return (float)value; } } } catch { } return battery.batteryLife; } private static void RefillAllArenaItemBatteries() { try { ItemBattery[] array = Object.FindObjectsOfType<ItemBattery>(); int num = 0; foreach (ItemBattery val in array) { if (!((Object)(object)val == (Object)null) && !SemiFunc.RunIsShop() && !IsBatteryAlreadyFull(val)) { ForceBatteryFull(val); num++; } } if (CfgWriteSpawnLog.Value) { Log.LogInfo((object)("Arena periodic battery refill: changed=" + num + " scanned=" + array.Length)); } } catch (Exception ex) { Log.LogError((object)("Failure: RefillAllArenaItemBatteries\n" + ex)); } } private static void ForceBatteryFull(ItemBattery battery) { if ((Object)(object)battery == (Object)null) { return; } try { int batteryBarsValue = GetBatteryBarsValue(battery); if (ItemBatteryFieldBatteryLife != null) { ItemBatteryFieldBatteryLife.SetValue(battery, 100f); } else { battery.batteryLife = 100f; } if (ItemBatteryFieldBatteryLifeInt != null) { ItemBatteryFieldBatteryLifeInt.SetValue(battery, batteryBarsValue); } if (ItemBatteryFieldBatteryLifeCountBars != null) { ItemBatteryFieldBatteryLifeCountBars.SetValue(battery, batteryBarsValue); } if (ItemBatteryFieldBatteryLifeCountBarsPrev != null) { ItemBatteryFieldBatteryLifeCountBarsPrev.SetValue(battery, batteryBarsValue); } if (ItemBatteryFieldDrainRate != null) { ItemBatteryFieldDrainRate.SetValue(battery, 0f); } if (ItemBatteryFieldDrainTimer != null) { ItemBatteryFieldDrainTimer.SetValue(battery, 0f); } if (ItemBatteryFieldChargeRate != null) { ItemBatteryFieldChargeRate.SetValue(battery, 0f); } if (ItemBatteryFieldChargeTimer != null) { ItemBatteryFieldChargeTimer.SetValue(battery, 0f); } battery.BatteryToggle(true); battery.OverrideBatteryShow(0.2f); if (ItemBatteryMethodBatteryFullPercentChange != null) { ItemBatteryMethodBatteryFullPercentChange.Invoke(battery, new object[2] { batteryBarsValue, false }); } else { battery.SetBatteryLife(100); } } catch (Exception ex) { Log.LogError((object)("Failure: ForceBatteryFull\n" + ex)); } } } }