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 Quads Arena v0.4.3
plugins/Arena.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DHack.Shared; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially or fully created with the assistance of Generative AI (Claude Code).")] [assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.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 Arena { internal static class Armoury { internal enum Slot { Weapon, Shield, Helmet, Chest, Legs } internal static readonly string[] SlotWords = new string[5] { "weapon", "shield", "helmet", "chest", "legs" }; private static readonly int[] Base = new int[7] { 20, 80, 200, 400, 700, 1100, 1600 }; private static readonly int[] CoinsByLand = new int[7] { 6, 12, 20, 30, 42, 56, 72 }; internal static int Cap => Mathf.Min(Contest.Tier + 1, Roster.TierNames.Length - 1); private static string[] List(Slot slot, int style) { return slot switch { Slot.Weapon => Kit.Weapons[Mathf.Clamp(style, 0, Kit.Styles.Length - 1)], Slot.Shield => Kit.Shields, _ => Kit.Armour.Select((string[] a) => a[(int)(slot - 2)]).ToArray(), }; } private static string PrefabOf(string entry) { int num = entry.IndexOf(':'); if (num <= 0) { return entry; } return entry.Substring(0, num); } private static int QualityOf(string entry) { int num = entry.IndexOf(':'); if (num <= 0 || !int.TryParse(entry.Substring(num + 1), out var result)) { return 2; } return result; } internal static List<Slot> Slots(int style, bool fists) { if (fists) { return new List<Slot> { Slot.Helmet, Slot.Chest, Slot.Legs }; } List<Slot> list = new List<Slot> { Slot.Weapon, Slot.Shield, Slot.Helmet, Slot.Chest, Slot.Legs }; if (style == 4) { list.Remove(Slot.Shield); } return list; } internal static int TierOf(Player player, Slot slot, int style) { string[] array = List(slot, style); int num = -1; foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems()) { string text = (((Object)(object)allItem.m_dropPrefab != (Object)null) ? ((Object)allItem.m_dropPrefab).name : ""); for (int num2 = array.Length - 1; num2 > num; num2--) { if (PrefabOf(array[num2]) == text && allItem.m_quality >= QualityOf(array[num2])) { num = num2; break; } } } return num; } internal static int Price(Slot slot, int tier) { return Mathf.RoundToInt((float)Base[Mathf.Clamp(tier, 0, Base.Length - 1)] * slot switch { Slot.Shield => 0.4f, Slot.Weapon => 1f, _ => 0.6f, }); } internal static bool Next(Player player, Slot slot, int style, out int tier, out string prefab, out int quality, bool capped = false) { tier = TierOf(player, slot, style) + 1; prefab = null; quality = 2; if ((capped && tier > Cap) || tier >= Roster.TierNames.Length) { return false; } string[] array = List(slot, style); prefab = PrefabOf(array[tier]); quality = QualityOf(array[tier]); return Roster.Has(prefab); } internal static string Name(Player player, Slot slot, int style) { int num = TierOf(player, slot, style); if (num < 0) { return Translations.T("arena_slot_none"); } string[] array = List(slot, style); return Contest.ItemName(PrefabOf(array[num])) + ((QualityOf(array[num]) > 2) ? (" ★" + QualityOf(array[num])) : ""); } internal static (string Prefab, int Amount, int Quality, string Loan)? Random(Player player, int style, bool fists, string loan) { int tier2; string prefab2; int quality2; List<Slot> list = (from s in Slots(style, fists) where Next(player, s, style, out tier2, out prefab2, out quality2, capped: true) select s).ToList(); if (list.Count == 0) { return null; } Slot slot = list[Random.Range(0, list.Count)]; Next(player, slot, style, out var _, out var prefab, out var quality, capped: true); return (prefab, 1, quality, loan); } internal static void Bought(Player player, Slot slot, string prefab, int style) { if (Next(player, slot, style, out var tier, out var prefab2, out var quality) && !(prefab2 != prefab)) { ItemData val = ((IEnumerable<ItemData>)((Humanoid)player).GetInventory().GetAllItems()).LastOrDefault((Func<ItemData, bool>)((ItemData i) => (Object)(object)i.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == prefab && !Kit.IsLoan(i))); if (val != null) { val.m_quality = Mathf.Clamp(quality, 1, val.m_shared.m_maxQuality); val.m_durability = val.GetMaxDurability(); val.m_customData["dh_arena_loan"] = tier.ToString(); ((Humanoid)player).EquipItem(val, false); Tidy(player, style); } } } internal static void Tidy(Player player, int style) { if ((Object)(object)player == (Object)null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); Slot[] array = new Slot[5] { Slot.Weapon, Slot.Shield, Slot.Helmet, Slot.Chest, Slot.Legs }; foreach (Slot slot in array) { string[] array2 = List(slot, style); int num = TierOf(player, slot, style); if (num < 0) { continue; } foreach (ItemData item in inventory.GetAllItems().ToList()) { if (Kit.IsLoan(item) && !item.m_equipped && !((Object)(object)item.m_dropPrefab == (Object)null)) { string name = ((Object)item.m_dropPrefab).name; int num2 = Array.FindLastIndex(array2, (string e) => PrefabOf(e) == name && item.m_quality >= QualityOf(e)); if (num2 >= 0 && num2 < num) { inventory.RemoveItem(item); } } } } } internal static int MealPrice(int land) { return 10 + 10 * land; } internal static int HealingPrice(int land) { return 15 + 12 * land; } internal static int StaminaPrice(int land) { return 12 + 8 * land; } internal static int ArrowsPrice(int land) { return 10 + 8 * land; } internal static int SwitchPrice(int tier) { return Mathf.Max(20, Price(Slot.Weapon, Mathf.Max(1, tier)) / 2); } internal static void Switched(Player player, int style, string prefab, int tier, int quality) { ItemData val = ((IEnumerable<ItemData>)((Humanoid)player).GetInventory().GetAllItems()).LastOrDefault((Func<ItemData, bool>)((ItemData i) => (Object)(object)i.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == prefab && !Kit.IsLoan(i))); if (val == null) { return; } val.m_quality = Mathf.Clamp(quality, 1, val.m_shared.m_maxQuality); val.m_durability = val.GetMaxDurability(); val.m_customData["dh_arena_loan"] = tier.ToString(); Contest.Style = style; if (style == 4) { (string, int)[] array = new(string, int)[2] { (Kit.ArrowFor(tier), 60), (Kit.Knives[Mathf.Clamp(tier, 0, Kit.Knives.Length - 1)].Split(new char[1] { ':' })[0], 1) }; for (int num = 0; num < array.Length; num++) { (string, int) tuple = array[num]; if (tuple.Item1 != null && Roster.Has(tuple.Item1)) { KeepApart.AddMarked(((Humanoid)player).GetInventory(), tuple.Item1, tuple.Item2, 2, tier.ToString()); } } } ((Humanoid)player).EquipItem(val, false); } internal static void Spill(Vector3 at, int land, int level, bool champion) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) float num = Rules.Multiplier * (1f + Crowd.Favour / 200f) * Plugin.Rewards.Value / 100f; int amount = Mathf.Max(1, Mathf.RoundToInt((float)CoinsByLand[Mathf.Clamp(land, 0, CoinsByLand.Length - 1)] * Random.Range(0.8f, 1.2f) * (1f + 0.5f * (float)(level - 1)) * (champion ? 5f : 1f) * num)); Drop("Coins", amount, at); } internal static void Drop(string prefab, int amount, Vector3 at) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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) GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null || amount <= 0) { return; } int num = Mathf.Max(1, val2.m_itemData.m_shared.m_maxStackSize); while (amount > 0) { int num2 = Mathf.Min(amount, num); amount -= num2; GameObject val3 = Object.Instantiate<GameObject>(val, at + Vector3.up * 0.8f + Random3(), Quaternion.identity); ItemDrop component = val3.GetComponent<ItemDrop>(); if (component != null) { component.SetStack(num2); } Rigidbody component2 = val3.GetComponent<Rigidbody>(); if (component2 != null) { component2.AddForce(Vector3.up * 3f + Random3() * 2f, (ForceMode)2); } } } private static Vector3 Random3() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Random.Range(-0.4f, 0.4f), 0f, Random.Range(-0.4f, 0.4f)); } } internal class Armourer : MonoBehaviour, Hoverable, Interactable { private Trader _trader; internal static readonly Dictionary<TradeItem, Armoury.Slot> Upgrades = new Dictionary<TradeItem, Armoury.Slot>(); internal static readonly Dictionary<TradeItem, (int Style, int Tier, int Quality)> Switches = new Dictionary<TradeItem, (int, int, int)>(); public string GetHoverText() { return Localization.instance.Localize("$arena_armourer\n[<color=yellow><b>$KEY_Use</b></color>] $arena_armourer_wares\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $arena_armourer_ready"); } public string GetHoverName() { return Translations.T("arena_armourer"); } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (hold || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } if (alt) { Contest.ReadyEarly(); return true; } if ((Object)(object)_trader == (Object)null) { GameObject val = new GameObject("ArmourerStore"); val.transform.SetParent(((Component)this).transform, false); _trader = val.AddComponent<Trader>(); ((Behaviour)_trader).enabled = false; } _trader.m_name = Translations.T("arena_armourer"); Restock(_trader); StoreGui instance = StoreGui.instance; if (instance != null) { instance.Show(_trader); } return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } internal static bool Ours(Trader trader) { if ((Object)(object)trader != (Object)null && (Object)(object)((Component)trader).transform.parent != (Object)null) { return (Object)(object)((Component)((Component)trader).transform.parent).GetComponent<Armourer>() != (Object)null; } return false; } internal static void Restock(Trader trader) { Player localPlayer = Player.m_localPlayer; trader.m_items.Clear(); Upgrades.Clear(); Switches.Clear(); if ((Object)(object)localPlayer == (Object)null) { return; } int tier = Contest.Tier; int style = Contest.Style; foreach (Armoury.Slot item in Armoury.Slots(style, Rules.Fists)) { if (Armoury.Next(localPlayer, item, style, out var tier2, out var prefab, out var quality)) { GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); ItemDrop val = ((prefab2 != null) ? prefab2.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null)) { ItemData val2 = val.m_itemData.Clone(); val2.m_quality = Mathf.Clamp(quality, 1, val2.m_shared.m_maxQuality); TradeItem val3 = Item(val, 1, Armoury.Price(item, tier2), Translations.T("arena_upgrade_tip", "<color=orange>" + Translations.T("arena_upgrade_" + Armoury.SlotWords[(int)item]) + "</color>", Armoury.Name(localPlayer, item, style)) + "\n\n" + val2.GetTooltip(1)); trader.m_items.Add(val3); Upgrades[val3] = item; } } } if (!Rules.Fists) { int num = Mathf.Max(0, Armoury.TierOf(localPlayer, Armoury.Slot.Weapon, style)); for (int i = 0; i < Kit.Styles.Length; i++) { if (i != style) { string text = Kit.Weapons[i][num]; string text2 = text.Split(new char[1] { ':' })[0]; int result; int num2 = ((text.Contains(":") && int.TryParse(text.Split(new char[1] { ':' })[1], out result)) ? result : 2); GameObject prefab3 = ZNetScene.instance.GetPrefab(text2); ItemDrop val4 = ((prefab3 != null) ? prefab3.GetComponent<ItemDrop>() : null); if (!((Object)(object)val4 == (Object)null)) { ItemData val5 = val4.m_itemData.Clone(); val5.m_quality = Mathf.Clamp(num2, 1, val5.m_shared.m_maxQuality); TradeItem val6 = Item(val4, 1, Armoury.SwitchPrice(num), Translations.T("arena_switch_tip", "<color=orange>" + Translations.T($"arena_fight_with_{i}") + "</color>", Armoury.Name(localPlayer, Armoury.Slot.Weapon, style)) + "\n\n" + val5.GetTooltip(1)); trader.m_items.Add(val6); Switches[val6] = (i, num, num2); } } } } if (!Rules.NoFood) { foreach (var item2 in Kit.Menu(tier)) { Add(trader, item2.Prefab, 1, Armoury.MealPrice(tier)); } Add(trader, Kit.Meads[Mathf.Clamp(tier, 0, Kit.Meads.Length - 1)], 1, Armoury.HealingPrice(tier)); Add(trader, (tier < 3) ? "MeadStaminaMinor" : ((tier < 6) ? "MeadStaminaMedium" : "MeadStaminaLingering"), 1, Armoury.StaminaPrice(tier)); } if (style == 4 && !Rules.Fists && Kit.ArrowFor(tier) != null) { Add(trader, Kit.ArrowFor(tier), 30, Armoury.ArrowsPrice(tier)); } } private static void Add(Trader trader, string prefab, int stack, int price) { GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); ItemDrop val = ((prefab2 != null) ? prefab2.GetComponent<ItemDrop>() : null); if ((Object)(object)val != (Object)null) { trader.m_items.Add(Item(val, stack, price, Kit.Keeps(prefab, Contest.Tier) ? "" : (Translations.T("arena_lent_tip", "<color=orange>" + Translations.T("arena_lent") + "</color>") + "\n\n" + val.m_itemData.GetTooltip(stack)))); } } private static TradeItem Item(ItemDrop drop, int stack, int price, string tooltip) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown return new TradeItem { m_prefab = drop, m_stack = stack, m_price = price, m_tooltip = (tooltip ?? ""), m_buyPlayerEffects = new EffectList(), m_name = "" }; } } [HarmonyPatch(typeof(Trader), "OnBought")] internal static class Trader_OnBought_Armourer { private static bool Prefix(Trader __instance, TradeItem item) { if (!Armourer.Ours(__instance)) { return true; } Player localPlayer = Player.m_localPlayer; (int, int, int) value2; if ((Object)(object)localPlayer != (Object)null && Armourer.Upgrades.TryGetValue(item, out var value)) { Armoury.Bought(localPlayer, value, ((Object)((Component)item.m_prefab).gameObject).name, Contest.Style); } else if ((Object)(object)localPlayer != (Object)null && Armourer.Switches.TryGetValue(item, out value2)) { Armoury.Switched(localPlayer, value2.Item1, ((Object)((Component)item.m_prefab).gameObject).name, value2.Item2, value2.Item3); } else if ((Object)(object)localPlayer != (Object)null) { Kit.LendIfFromBeyond(localPlayer, ((Object)((Component)item.m_prefab).gameObject).name, Contest.Tier); } Net.Sound("cheer"); Armourer.Restock(__instance); return false; } } [HarmonyPatch(typeof(Trader), "OnSold")] internal static class Trader_OnSold_Armourer { private static bool Prefix(Trader __instance) { if (!Armourer.Ours(__instance)) { return true; } Armourer.Restock(__instance); return false; } } internal static class Contest { internal enum PhaseKind { None, Ready, Arming, Countdown, Spawning, Fighting, Break, Victory } internal enum KindOf { Road, Champion, Endless, Trial } private enum Outcome { Win, CashOut, Yield, Died, TimeUp, LeftRing, Carried, Aborted, CalledOff } private struct Item { public string Prefab; public string Name; public int Level; public bool Champion; } private sealed class Foe { public GameObject Go; public Character Char; public bool Champion; public bool Counted; public string Prefab; public Vector3 LastPos; public int Level; } internal static PhaseKind Phase; internal static KindOf Kind; internal static string Title = ""; internal static string TitleLine = ""; internal static int Round; internal static int Rounds; internal static int Tier; internal static int Stake; internal static int Fee; internal static int Style; internal static bool Daily; private static bool _stowed; private static string _look = ""; private static readonly List<string> Trophies = new List<string>(); private static readonly List<Foe> Foes = new List<Foe>(); private static readonly Queue<Item> Queue = new Queue<Item>(); private const float ReadySeconds = 90f; private static int _nextPen; private static float _spawnedAt; private static float _timer; private static float _spawnTimer; private static float _lastKill; private static float _outside; private static float _closeAt; private static float _yieldAt; private static float _roundLeft; private static float _lastWarn; private static float _lastParryShout; private static float _peak; private static float _purseCoins; private static float _victoryAt; private static float _offFloor; private static float _nextChant; private static int _victoryStep; private static bool _toChest; private static bool _crowned; private static readonly List<(string Prefab, int Amount, int Quality, string Loan)> PrizeItems = new List<(string, int, int, string)>(); private static readonly Dictionary<string, float> Mats = new Dictionary<string, float>(); private static int _combo; private static int _kills; private static int _count; private static bool _knockedOut; private static bool _hurtThisRound; private static float _tombUntil; private static Vector3 _tombCentre; private static float _tombRadius; internal const string Stage = "Platform"; private static readonly MethodInfo SetTarget = AccessTools.Method(typeof(MonsterAI), "SetTarget", new Type[1] { typeof(Character) }, (Type[])null); internal static bool Active => Phase != PhaseKind.None; internal static bool Fighting { get { if (Phase != PhaseKind.Spawning) { return Phase == PhaseKind.Fighting; } return true; } } internal static bool Waiting => Phase == PhaseKind.Ready; internal static int FoesLeft => Queue.Count + Foes.Count((Foe f) => !f.Counted); internal static Vector3 Centre => Site.Centre; internal static int Kills => _kills; internal static float LastKillTime => _lastKill; internal static float RoundLeft => _roundLeft; internal static bool Endless => Kind == KindOf.Endless; internal static int PurseCoins => Mathf.RoundToInt(_purseCoins); internal static bool Lent { get { if (Kind != KindOf.Road) { return Kind == KindOf.Trial; } return true; } } internal static bool Lands { get { if (Kind != KindOf.Road) { return Kind == KindOf.Trial; } return true; } } internal static int LandRound => (Mathf.Max(1, Round) - 1) % 3 + 1; internal static bool TombPending => Time.time < _tombUntil; private static string FightCover() { string[] array = Layout.Props.Keys.Where((string k) => k != "Platform").ToArray(); if (array.Length == 0 || !(Random.value < 0.85f)) { return null; } return array[Random.Range(0, array.Length)]; } internal static string TimerLabel(out float seconds) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) string result = Favours.DemandLabel(out seconds); if (seconds >= 0f) { return result; } seconds = _timer; string text = ((object)Plugin.YieldKey.Value/*cast due to .constrained prefix*/).ToString(); switch (Phase) { case PhaseKind.Ready: return Translations.T("arena_walk_in"); case PhaseKind.Arming: if (!Show.ChestEmptied) { return Translations.T("arena_timer_arming"); } return Translations.T("arena_timer_arming_done"); case PhaseKind.Break: if (!Lent) { return Translations.T("arena_timer_next_round") + " · " + Translations.T("arena_timer_leave_purse", text); } return Translations.T(Show.ArmourerStanding ? "arena_timer_break_armourer" : "arena_timer_break_coins") + " · " + Translations.T("arena_timer_leave_coins", text); default: seconds = -1f; return ""; } } internal static bool FoeWithin(Vector3 at, float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Foes.Any(delegate(Foe f) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) if (!f.Counted && (Object)(object)f.Go != (Object)null) { Vector3 val = f.Go.transform.position - at; return ((Vector3)(ref val)).sqrMagnitude < range * range; } return false; }); } internal static string KindName(KindOf kind) { return Translations.T(KindKey(kind)); } internal static string KindKey(KindOf kind) { return "arena_kind_" + KindWord(kind); } private static string KindWord(KindOf kind) { return kind switch { KindOf.Endless => "endless", KindOf.Champion => "champion", KindOf.Road => "road", _ => "trial", }; } internal static int FeeFor(KindOf kind, int tier) { if (Ladder.Get("fights") == 0) { return 0; } return Mathf.RoundToInt(kind switch { KindOf.Champion => 50f + 40f * (float)tier, KindOf.Trial => 60f + 30f * (float)tier, KindOf.Road => 150f, _ => 40f + 30f * (float)tier, } * Plugin.EntryFee.Value / 100f); } internal static void TodaysPlan(out int tier, out int style, out bool fists, out bool noFood, out bool hard, out bool timed) { Random random = new Random(Ladder.Today * 31 + 7); style = random.Next(Kit.Styles.Length); int num = Roster.Beaten(); tier = Mathf.Max(0, num - random.Next(Mathf.Min(2, num + 1))); bool[] array = new bool[3]; int num2 = 1 + random.Next(2); for (int i = 0; i < num2; i++) { array[random.Next(3)] = true; } fists = array[0]; noFood = false; hard = array[1]; timed = array[2]; } internal static string Start(KindOf kind, int tier, int style, bool fists, bool noFood, bool hard, bool timed, int stake, bool daily) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !Site.Known || !Scenery.Built) { return Translations.T("arena_not_ready"); } if (Active) { return Translations.T("arena_contest_on"); } if (Duel.Active) { return Translations.T("arena_in_duel"); } if (Net.RemoteFight) { return Translations.T("arena_busy_wait", Net.BusyText); } if (kind == KindOf.Road) { tier = 0; } tier = Mathf.Clamp(tier, 0, Roster.TierNames.Length - 1); if (Roster.Pool(tier).Count == 0) { return Translations.T("arena_no_one"); } if (kind == KindOf.Endless || kind == KindOf.Road) { stake = 0; } bool flag = kind == KindOf.Road || kind == KindOf.Trial; if (flag && Kit.Stowed(localPlayer)) { return Translations.T("arena_still_held"); } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); int num = FeeFor(kind, tier); if (inventory.CountItems("$item_coins", -1, true) < num + stake) { if (stake <= 0) { return Translations.T("arena_no_coins", num); } return Translations.T("arena_no_coins_stake", num, stake); } if (num + stake > 0) { inventory.RemoveItem("$item_coins", num + stake, -1, true); } Stake = stake; Fee = num; Daily = daily; Kind = kind; Tier = tier; Style = ((style < 0) ? Random.Range(0, Kit.Styles.Length) : Mathf.Clamp(style, 0, Kit.Styles.Length - 1)); Rules.Set(fists, noFood, hard, timed); Rounds = kind switch { KindOf.Trial => 3, KindOf.Road => 3 * Roster.TierNames.Length, _ => (kind == KindOf.Champion) ? 1 : 0, }; Title = ((kind == KindOf.Road) ? "The Long Road" : (kind.ToString() + " - " + Roster.TierNames[Tier])); TitleLine = ((kind == KindOf.Road) ? Words.Line(KindKey(kind)) : Words.Line("arena_title", Words.Word(KindKey(kind)), Words.Land(Tier))); Round = 0; _kills = 0; _combo = 0; _outside = 0f; _knockedOut = false; _closeAt = 0f; _yieldAt = 0f; _purseCoins = 0f; _peak = 0f; _stowed = false; _look = ""; Mats.Clear(); Trophies.Clear(); Foes.Clear(); Queue.Clear(); Net.Props(FightCover()); Show.ClearFloor(); Crowd.Open(); Favours.Reset(); Net.Gate(Scenery.MainGrate, 90f); Net.Door(90f); Net.Shout(Words.Line("arena_call_to_ring"), Words.Line("arena_call_to_ring_sub", localPlayer.GetPlayerName()), 6f); Phase = PhaseKind.Ready; _timer = 90f; _count = 4; if (flag) { Hud.Say(Translations.T("arena_say_lent")); } Hud.Say(Translations.T(flag ? "arena_say_play_lent" : "arena_say_play")); Plugin.Log.LogInfo((object)($"Contest started: {Title}, rules {Rules.Names()}, fee {num}, stake {stake}" + (flag ? (", " + Kit.Styles[Style]) : ""))); return null; } internal static void Tick(float dt) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) if (_closeAt > 0f && Time.time >= _closeAt) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !Site.OnFloor(((Component)localPlayer).transform.position, 2f) || Time.time > _closeAt + 45f) { _closeAt = 0f; if (!Duel.Active && !Net.RemoteFight) { Crowd.Close(bow: true); } Net.Props(null); } } if (!Active) { return; } Player localPlayer2 = Player.m_localPlayer; if ((Object)(object)localPlayer2 == (Object)null) { Abort("You left the world."); return; } if (Phase == PhaseKind.Victory) { TickVictory(localPlayer2, dt); return; } if (((Character)localPlayer2).IsDead()) { End(Outcome.Died); return; } if (_knockedOut) { End(Outcome.Carried); return; } _peak = Mathf.Max(_peak, Crowd.Favour); KeyboardShortcut value = Plugin.YieldKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !Window.IsOpen) { bool flag = Phase == PhaseKind.Break || Phase == PhaseKind.Arming; if (_yieldAt > 0f && Time.time - _yieldAt < 3f) { End(flag ? Outcome.CashOut : Outcome.Yield); return; } _yieldAt = Time.time; Hud.Say(Translations.T(Lent ? "arena_say_yield_coins" : (flag ? "arena_say_yield_purse" : "arena_say_yield_half"))); } if (Phase == PhaseKind.Ready) { _timer -= dt; if (Site.OnFloor(((Component)localPlayer2).transform.position, -1f)) { Net.Gate(Scenery.MainGrate, 0f); Net.Door(0f); if (Lent) { if (!Kit.Stow(localPlayer2)) { End(Outcome.Aborted); Hud.Say(Translations.T("arena_say_stow_failed")); return; } _stowed = true; localPlayer2.ClearFood(); } else { Rules.Strip(localPlayer2); } ((Character)localPlayer2).Heal(((Character)localPlayer2).GetMaxHealth(), true); ((Character)localPlayer2).AddStamina(((Character)localPlayer2).GetMaxStamina()); _look = Figures.LookOf(localPlayer2); string text = Words.Line("arena_call_intro", Words.Word(KindKey(Kind))); Net.Sound("gong"); if (Lent) { Show.PopChest(1, Kit.Outfit(Tier, Style, Rules.Fists, !Rules.NoFood)); Net.Shout(text, Words.Then(Lines.Welcome(localPlayer2.GetPlayerName()), Words.Line("arena_call_arm")), 5f); Phase = PhaseKind.Arming; _timer = 40f; } else { string text2 = Words.Rules(Rules.Fists, Rules.NoFood, Rules.Hard, Rules.Timed); Net.Shout(text, Words.Then(Lines.Welcome(localPlayer2.GetPlayerName()), (Stake > 0) ? Words.Line("arena_call_rules_stake", text2, Stake) : Words.Line("arena_call_rules", text2)), 5f); Phase = PhaseKind.Countdown; _timer = 5f; _count = 4; } } else if (_timer <= 0f) { End(Outcome.Aborted); Hud.Say(Translations.T("arena_say_no_show")); } return; } if (!Site.OnFloor(((Component)localPlayer2).transform.position, 1.5f)) { _outside += dt; if (Time.time - _lastWarn > 1f) { _lastWarn = Time.time; Hud.Say(Translations.T("arena_say_get_back", Mathf.CeilToInt(8f - _outside))); } if (_outside > 8f) { End(Outcome.LeftRing); return; } } else { _outside = Mathf.Max(0f, _outside - dt * 2f); } switch (Phase) { case PhaseKind.Arming: _timer -= dt; if (Show.ChestEmptied && _timer > 6f) { _timer = 6f; } if (_timer <= 0f) { Show.TakeChest(); Phase = PhaseKind.Countdown; _timer = 3.5f; _count = 4; } break; case PhaseKind.Countdown: { _timer -= dt; int num = Mathf.CeilToInt(_timer); if (num < _count && num >= 1 && num <= 3) { _count = num; Hud.Count(num.ToString()); } if (_timer <= 0f) { Hud.Count(Translations.T("arena_fight")); Net.Sound("cheer"); BeginRound(1); } break; } case PhaseKind.Spawning: case PhaseKind.Fighting: if (Phase == PhaseKind.Spawning) { _spawnTimer -= dt; if (_spawnTimer <= 0f && Queue.Count > 0) { Spawn(Queue.Dequeue(), localPlayer2); _spawnTimer = 1.1f; } if (Queue.Count == 0) { Phase = PhaseKind.Fighting; } } CheckFoes(localPlayer2); if (Rules.Timed) { float roundLeft = _roundLeft; _roundLeft -= dt; if (roundLeft > 10f && _roundLeft <= 10f) { Net.Shout(Words.Line("arena_call_ten_seconds"), "", 1.5f); } if (_roundLeft <= 0f) { End(Outcome.TimeUp); break; } } if (Phase == PhaseKind.Fighting && Foes.All((Foe f) => f.Counted) && Queue.Count == 0) { RoundCleared(localPlayer2); } break; case PhaseKind.Break: _timer -= dt; if (!Lent && Show.ChestEmptied && _timer > 6f) { _timer = 6f; } if (_timer <= 0f) { Show.TakeChest(); Show.Armourer(on: false); if (Lent) { Armoury.Tidy(localPlayer2, Style); } BeginRound(Round + 1); } break; } } private static void BeginRound(int n) { Round = n; Queue.Clear(); Foes.Clear(); _hurtThisRound = false; int num = (n - 1) % 3; if (Kind == KindOf.Road && num == 0 && n > 1) { Show.TakeChest(); Net.Props(FightCover()); } bool flag; int num2; float lean; int num3; if (Lands) { if (Kind == KindOf.Road) { Tier = Mathf.Min((n - 1) / 3, Roster.TierNames.Length - 1); } flag = num == 2; num2 = 3 + num + (Rules.Hard ? 2 : 0) - (flag ? 3 : 0); lean = (float)num / 2f; num3 = 1 + (Rules.Hard ? 1 : 0); } else if (Kind == KindOf.Champion) { flag = true; num2 = (Rules.Hard ? 2 : 0); lean = 0.5f; num3 = 1 + (Rules.Hard ? 1 : 0); } else { flag = n % 5 == 0; num2 = Mathf.Min(2 + n, 12) + (Rules.Hard ? 1 : 0) - (flag ? 2 : 0); lean = Mathf.Min(1f, (float)n / 8f); num3 = 1 + (n - 1) / 5 + (Rules.Hard ? 1 : 0); } for (int i = 0; i < num2; i++) { string text = Roster.Pick(Tier, lean); if (text != null) { int num4 = num3 + ((Lands && num >= 1 && Random.value < 0.3f) ? 1 : 0); Queue.Enqueue(new Item { Prefab = text, Level = Mathf.Clamp(num4, 1, 3) }); } } if (flag) { string text2 = Roster.Champion(Tier); if (text2 != null) { Queue.Enqueue(new Item { Prefab = text2, Name = Roster.ChampionName(), Level = Roster.ChampionLevel(Tier, text2, Kind, n, Rules.Hard), Champion = true }); } } if (Queue.Count == 0) { End(Outcome.CalledOff); return; } _roundLeft = 90f + (flag ? 30f : 0f); Phase = PhaseKind.Spawning; _spawnTimer = 1.4f; string text3 = Words.Land(Tier); string text4 = ((Kind == KindOf.Champion) ? Words.Line("arena_call_the_champion") : ((Kind == KindOf.Endless) ? Words.Line("arena_call_wave", n) : ((!flag) ? ((Kind == KindOf.Road) ? Words.Line("arena_call_land_round", text3, num + 1) : Words.Line("arena_call_round", n)) : ((Kind == KindOf.Road) ? Words.Line("arena_call_champion_of", text3) : Words.Line("arena_call_final_round"))))); string sub = ((flag && Kind != KindOf.Champion) ? Words.Line("arena_call_champion_comes") : Lines.RoundCall(Queue.Count)); Net.Shout(text4, sub, 3.5f); Net.Sound("gong"); if (n > 1) { Net.Sound("cheer"); } } private static void RoundCleared(Player player) { //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) int num = (Round - 1) % 3; float units = (Lands ? (0.7f + 0.4f * (float)num) : ((Kind == KindOf.Endless) ? (0.5f + 0.15f * (float)Round) : 3f)); if (!_hurtThisRound) { Crowd.Gain(12f, cheer: false); Net.Shout(Words.Line("arena_call_flawless"), Words.Line("arena_call_flawless_sub"), 2.2f); } if (!Lent) { AddToPurse(units); } if (Kind == KindOf.Endless) { Ladder.Best("bestwave" + Tier, Round); } else if (Kind == KindOf.Road) { Ladder.Best("road", Round); } else { Ladder.Best("bestround" + Tier, Round); } _look = Figures.LookOf(player); if (Rounds > 0 && Round >= Rounds) { StartVictory(player); return; } Crowd.Gain(8f, cheer: false); Net.Sound("applause"); Phase = PhaseKind.Break; _timer = 12f; ((Character)player).AddStamina(((Character)player).GetMaxStamina()); if (Kind == KindOf.Road && num == 2) { int tier = Mathf.Min(Tier + 1, Roster.TierNames.Length - 1); ((Character)player).Heal(((Character)player).GetMaxHealth(), true); Net.Props("Platform"); if (Lent) { List<(string, int, int, string)> list = new List<(string, int, int, string)>(); (string, int, int, string)? tuple = Armoury.Random(player, Style, Rules.Fists, Tier.ToString()); if (tuple.HasValue) { list.Add(tuple.Value); } else { list.Add(("Coins", Mathf.RoundToInt(60f * (float)(Tier + 1) * Plugin.Rewards.Value / 100f), 1, null)); } if (!Rules.NoFood && Random.value < 0.3f) { if (Random.value < 0.5f) { foreach (string item in Kit.Plate(Tier + 1, new Kit.Role[1]).Take(1)) { list.Add((item, 1, 1, Tier.ToString())); } } else { list.Add((Kit.Meads[Mathf.Clamp(Tier + 1, 0, Kit.Meads.Length - 1)], 1, 1, Tier.ToString())); } } if (list.Count > 0) { Show.PopChest(3, list); } Show.Armourer(on: true); } Net.Sound("roar"); Net.Shout(Words.Line("arena_call_land_beaten", Words.Land(Tier)), Words.Then(Words.Line("arena_call_on_to", Words.Land(tier)), "-", Words.Line("arena_call_leave_coins", ((object)Plugin.YieldKey.Value/*cast due to .constrained prefix*/).ToString())), 7f); _timer = 50f; } else if (Lent) { Net.Shout(Words.Line("arena_call_round_cleared", Round), Words.Then(Words.Line("arena_call_pick_up_coins"), "-", Words.Line("arena_call_leave_them", ((object)Plugin.YieldKey.Value/*cast due to .constrained prefix*/).ToString())), 4.5f); ((Character)player).Heal(((Character)player).GetMaxHealth() * 0.3f, true); } else { Net.Shout(Words.Line((Kind == KindOf.Endless) ? "arena_call_wave_cleared" : "arena_call_round_cleared", Round), Words.Then(Words.Line("arena_call_your_purse", Words.Purse(PurseData())), "-", Words.Line("arena_call_leave_it", ((object)Plugin.YieldKey.Value/*cast due to .constrained prefix*/).ToString())), 4.5f); ((Character)player).Heal(((Character)player).GetMaxHealth() * 0.3f, true); } } private static void AddToPurse(float units) { float num = Rules.Multiplier * (1f + Crowd.Favour / 200f) * Plugin.Rewards.Value / 100f; _purseCoins += (float)(20 + 30 * Tier) * units * num; string text = ((Tier <= Roster.Beaten()) ? Roster.Material(Tier) : null); if (text != null) { Mats[text] = (Mats.TryGetValue(text, out var value) ? value : 0f) + (float)(2 + Tier) * 0.5f * units * num; } } internal static string PurseText() { if (Lent) { return Translations.T("arena_purse_bag", ((Object)(object)Player.m_localPlayer != (Object)null) ? ((Humanoid)Player.m_localPlayer).GetInventory().CountItems("$item_coins", -1, true) : 0); } return PurseText(PurseData()); } private static string PurseData() { return PurseCoins.ToString(CultureInfo.InvariantCulture) + ";" + string.Join(",", from m in Mats where Mathf.FloorToInt(m.Value) > 0 select m.Key + "*" + Mathf.FloorToInt(m.Value).ToString(CultureInfo.InvariantCulture)); } internal static string PurseText(string data) { string[] array = data.Split(new char[1] { ';' }); string text = Translations.T("arena_coins", array[0]); if (array.Length > 1) { foreach (var item in Counted(array[1])) { text = text + ", " + Translations.T("arena_prize_item", item.Amount, ItemName(item.Prefab)); } } return text; } private static IEnumerable<(string Prefab, int Amount)> Counted(string list) { string[] array = list.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { int num = text.IndexOf('*'); if (num < 0) { yield return (Prefab: text, Amount: 1); continue; } int.TryParse(text.Substring(num + 1), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result); yield return (Prefab: text.Substring(0, num), Amount: result); } } internal static string ItemName(string prefab) { object obj; if (!((Object)(object)ZNetScene.instance != (Object)null)) { obj = null; } else { GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); obj = ((prefab2 != null) ? prefab2.GetComponent<ItemDrop>() : null); } ItemDrop val = (ItemDrop)obj; if (!((Object)(object)val != (Object)null) || Localization.instance == null) { return prefab; } return Localization.instance.Localize(val.m_itemData.m_shared.m_name); } private static void Spawn(Item item, Player player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(item.Prefab) : null); if ((Object)(object)val == (Object)null) { return; } Vector3 val2 = Site.Centre; if (Layout.Pens.Count > 0) { Layout.Mark mark = null; for (int i = 0; i < Layout.Pens.Count; i++) { Layout.Mark mark2 = Layout.Pens[(_nextPen + i) % Layout.Pens.Count]; Vector3 val3 = Site.Point(mark2) - ((Component)player).transform.position; if (((Vector3)(ref val3)).magnitude > 8f || i == Layout.Pens.Count - 1) { mark = mark2; _nextPen = (_nextPen + i + 1) % Layout.Pens.Count; break; } } val2 = Site.Point(mark, 0.2f); Net.Gate(mark.Gate, 4f); } GameObject val4 = Object.Instantiate<GameObject>(val, val2, Quaternion.LookRotation(new Vector3(Site.Centre.x - val2.x, 0f, Site.Centre.z - val2.z))); Foe foe = new Foe { Go = val4, Char = val4.GetComponent<Character>(), Champion = item.Champion, Prefab = item.Prefab, LastPos = val2, Level = item.Level }; if ((Object)(object)foe.Char != (Object)null) { foe.Char.SetLevel(item.Level); if (!string.IsNullOrEmpty(item.Name)) { foe.Char.m_name = Words.Show(item.Name); } } CharacterDrop component = val4.GetComponent<CharacterDrop>(); if (component != null) { component.SetDropsEnabled(false); } MonsterAI component2 = val4.GetComponent<MonsterAI>(); if ((Object)(object)component2 != (Object)null) { component2.SetDespawnInDay(false); ((BaseAI)component2).SetHuntPlayer(true); ((BaseAI)component2).m_afraidOfFire = false; ((BaseAI)component2).m_avoidFire = false; component2.m_fleeIfLowHealth = 0f; component2.m_fleeIfHurtWhenTargetCantBeReached = false; component2.m_fleeIfNotAlerted = false; ((BaseAI)component2).Alert(); SetTarget?.Invoke(component2, new object[1] { player }); } else { BaseAI component3 = val4.GetComponent<BaseAI>(); if (component3 != null) { component3.SetHuntPlayer(true); } } ZNetView component4 = val4.GetComponent<ZNetView>(); if ((Object)(object)component4 != (Object)null && component4.IsValid()) { component4.GetZDO().Set("dh_arena", true); if (item.Champion) { component4.SetLocalScale(Vector3.one * 1.18f); } } Foes.Add(foe); _spawnedAt = Time.time; if (item.Champion) { Net.Shout(item.Name, Words.Line(Roster.Origin(Tier))); Net.Sound("horn"); Net.Sound("roar"); Net.Effect("fx_fireball_staff_explosion", val2 + Vector3.up * 1.2f); Net.Effect("fx_fireskeleton_nova", val2); } } private static void CheckFoes(Player player) { //IL_006b: 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) //IL_0080: 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_00ca: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_00f9: 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_011f: Unknown result type (might be due to invalid IL or missing references) foreach (Foe fo in Foes) { if (fo.Counted) { continue; } if ((Object)(object)fo.Go == (Object)null || (Object)(object)fo.Char == (Object)null || fo.Char.IsDead()) { fo.Counted = true; OnKill(fo, player); continue; } fo.LastPos = fo.Go.transform.position; if (!Site.OnFloor(fo.Go.transform.position, 6f) && Time.time - _spawnedAt > 8f) { Vector3 val = Site.World(new Vector3(0f, 0f, 0f)); Vector3 val2 = fo.Go.transform.position - Site.Centre; Vector3 val3 = val + ((Vector3)(ref val2)).normalized * (Layout.Floor - 3f); val3.y = Site.Ground(val3, Site.Centre.y) + 0.3f; fo.Go.transform.position = val3; } } } private static void OnKill(Foe f, Player player) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) _kills++; _combo = ((!(Time.time - _lastKill < 4f)) ? 1 : (_combo + 1)); _lastKill = Time.time; Favours.OnKill(); bool flag = ((Character)player).GetHealth() < ((Character)player).GetMaxHealth() * 0.25f; Crowd.Gain((f.Champion ? 30f : (4f + (float)_combo * 3f)) + (flag ? 8f : 0f), cheer: true); if (Lent) { Armoury.Spill(f.LastPos, Tier, f.Level, f.Champion); if (f.Champion && Tier <= Roster.Beaten()) { string text = Roster.Trophy(f.Prefab); string text2 = Roster.Material(Tier); if (text != null) { Armoury.Drop(text, 1, f.LastPos); } if (text2 != null) { Armoury.Drop(text2, Mathf.RoundToInt((float)(2 + Tier) * 1.5f * Plugin.Rewards.Value / 100f), f.LastPos); } } } if (f.Champion) { string text3 = ((!Lent && Tier <= Roster.Beaten()) ? Roster.Trophy(f.Prefab) : null); if (text3 != null) { Trophies.Add(text3); } Net.Shout(Words.Line("arena_call_champion_falls"), Lines.ChampionDown(), 3f); Net.Sound("roar"); } else if (flag) { Net.Shout(Words.Line("arena_call_close"), Words.Line("arena_call_close_sub"), 1.8f); } else if (_combo == 2) { Net.Shout(Words.Line("arena_call_double"), "", 1.5f); } else if (_combo == 3) { Net.Shout(Words.Line("arena_call_triple"), "", 1.5f); } else if (_combo >= 5) { Net.Shout(Words.Line("arena_call_unstoppable"), Words.Line("arena_call_in_a_row", _combo), 1.8f); } } internal static void OnBlock(bool perfect) { if (Fighting) { Favours.OnParry(perfect); Crowd.Gain(perfect ? 6f : 1f, perfect); if (perfect && Time.time - _lastParryShout > 4f) { _lastParryShout = Time.time; Net.Shout(Words.Line("arena_call_parry"), "", 1.2f); } } } internal static void OnHurt(float fraction) { if (Fighting && !(fraction <= 0f)) { _hurtThisRound = true; Favours.OnHurt(); Crowd.Hurt(Mathf.Min(3f, fraction * 15f)); } } internal static void Knockout() { _knockedOut = true; } internal static void NoteDeath() { //IL_0018: 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) if (Active) { _tombUntil = Time.time + 5f; _tombCentre = Site.Centre; _tombRadius = Layout.Floor; } } internal static Vector3 TombSpot(Vector3 died) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) _tombUntil = 0f; Vector3 val = Site.World(Layout.Arrival.Pos + new Vector3(Random.Range(-4f, 4f), 0f, 5f)); val.y = Site.Ground(val, Site.Origin.y) + 0.6f; return val; } private static void ClearFoes() { foreach (Foe fo in Foes) { if (!((Object)(object)fo.Go == (Object)null) && !fo.Counted) { ZNetView component = fo.Go.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.Destroy(); } else { Object.Destroy((Object)(object)fo.Go); } } } Foes.Clear(); Queue.Clear(); } internal static void Abort(string why) { if (Active) { if (Phase == PhaseKind.Victory) { FinishVictory(); } else { End(Outcome.Aborted); } } } private static void StartVictory(Player player) { Phase = PhaseKind.Victory; _victoryAt = Time.time; _victoryStep = 0; _offFloor = 0f; _nextChant = Time.time + 5f; _timer = 90f; ClearFoes(); Crowd.Set(100f); PrizeItems.Clear(); _toChest = true; Pay(player, Outcome.Win, beforeTheFight: false); _toChest = false; Net.Sound("roar"); Net.Sound("horn"); Net.Sound("applause"); Net.Props("Platform"); Net.Fireworks(18, 12f); Net.Celebrate(); } private static void TickVictory(Player player, float dt) { //IL_0191: Unknown result type (might be due to invalid IL or missing references) _timer -= dt; float num = Time.time - _victoryAt; string playerName = player.GetPlayerName(); if (_victoryStep == 0 && num > 4f) { _victoryStep = 1; Net.Shout(_crowned ? Words.Line("arena_call_crowned_" + KindWord(Kind)) : Words.Line("arena_call_triumphs", playerName), Words.Line(_crowned ? "arena_call_chants_name_statue" : "arena_call_chants_name", playerName), 5f); Net.Sound("horn"); } if (_victoryStep == 1 && num > 7f) { _victoryStep = 2; Show.PopChest(2, PrizeItems); Net.Sound("roar"); Hud.Say(Translations.T("arena_say_prize_chest")); } if (_victoryStep == 2 && num > 11f) { _victoryStep = 3; Net.Gate(Scenery.MainGrate, 120f); Net.Door(120f); Net.Shout(Words.Line("arena_call_take_a_bow"), Words.Line("arena_call_take_a_bow_sub"), 3f); Net.Fireworks(12, 9f); } if (Time.time > _nextChant) { _nextChant = Time.time + Random.Range(7f, 10f); Net.Sound((Random.value < 0.5f) ? "horn" : "cheer"); } if (!Site.OnFloor(((Component)player).transform.position, 2f)) { _offFloor += dt; } else { _offFloor = 0f; } if (((Character)player).IsDead() || _timer <= 0f || (_victoryStep >= 3 && _offFloor > 1.5f)) { FinishVictory(); } } internal static void ReadyEarly() { if ((Phase == PhaseKind.Break || Phase == PhaseKind.Arming) && _timer > 3f) { _timer = 3f; Net.Sound("roar"); } } private static void FinishVictory() { Player localPlayer = Player.m_localPlayer; Phase = PhaseKind.None; Show.Armourer(on: false); Show.TakeChest(); if (_stowed && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { Kit.Return(localPlayer); } _stowed = false; Rules.Restore(localPlayer); Rules.Clear(); Net.Gate(Scenery.MainGrate, 30f); Net.Door(45f); Guard.Grace(60f); _closeAt = Time.time + 6f; } private static void End(Outcome outcome) { Player localPlayer = Player.m_localPlayer; bool flag = Phase == PhaseKind.Ready; Phase = PhaseKind.None; ClearFoes(); Show.TakeChest(); Show.Armourer(on: false); if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && !flag && _look.Length == 0) { _look = Figures.LookOf(localPlayer); } if (_stowed && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) { Kit.Return(localPlayer); } _stowed = false; if ((Object)(object)localPlayer != (Object)null) { Pay(localPlayer, outcome, flag); } Rules.Restore(localPlayer); Rules.Clear(); if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && outcome == Outcome.Carried) { ((Character)localPlayer).SetHealth(((Character)localPlayer).GetMaxHealth() * 0.35f); } _knockedOut = false; Net.Gate(Scenery.MainGrate, flag ? 0f : 30f); Net.Door(flag ? 0f : 45f); Guard.Grace(60f); bool flag2 = outcome == Outcome.Win || outcome == Outcome.CashOut; if (flag2) { Net.Sound("roar"); Net.Sound("horn"); Net.Sound("applause"); } else { Net.Sound("boo"); } _closeAt = Time.time + (flag2 ? 8f : 5f); } private static void Pay(Player player, Outcome outcome, bool beforeTheFight) { bool flag = outcome == Outcome.Win; if (beforeTheFight) { if (Fee + Stake > 0) { Give("Coins", Fee + Stake, player); } return; } Ladder.Add("kills", _kills); Ladder.Add("fights", 1); Ladder.Best("favour", Mathf.RoundToInt(_peak)); if (outcome == Outcome.Died) { Ladder.Add("deaths", 1); } if (flag || (Kind == KindOf.Road && outcome == Outcome.CashOut && Round >= 3)) { Ladder.Add("wins", 1); Ladder.Add((Kind == KindOf.Champion) ? "champions" : ((Kind == KindOf.Road) ? "roads" : ((Kind == KindOf.Trial) ? "trials" : "hordes")), 1); } int num = ((Humanoid)player).GetInventory().CountItems("$item_coins", -1, true); if (Lent) { _purseCoins = (flag ? (((Kind == KindOf.Road) ? 250f : 80f) * (float)(Tier + 1) * Rules.Multiplier * Plugin.Rewards.Value / 100f) : 0f); Mats.Clear(); } float num2; switch (outcome) { default: num2 = 0.5f; break; case Outcome.Died: num2 = 0f; break; case Outcome.CashOut: case Outcome.CalledOff: num2 = 1f; break; case Outcome.Win: num2 = 1.25f; break; } float num3 = num2; bool flag2 = flag && Daily && !Ladder.DailyDone; if (flag2) { num3 *= 1.5f; Ladder.Set("daily", Ladder.Today); } int num4 = Mathf.RoundToInt(_purseCoins * num3); int num5 = (flag ? (Stake * 2) : ((outcome == Outcome.CalledOff) ? Stake : 0)); List<string> list = ((outcome != Outcome.Died) ? Trophies.Distinct().ToList() : new List<string>()); if (num4 + num5 > 0) { Hand("Coins", num4 + num5); } List<string> list2 = new List<string>(); foreach (KeyValuePair<string, float> mat in Mats) { int num6 = Mathf.FloorToInt(mat.Value * num3); if (num6 > 0) { Hand(mat.Key, num6); list2.Add(mat.Key + "*" + num6.ToString(CultureInfo.InvariantCulture)); } } foreach (string item in list) { Hand(item, 1); list2.Add(item); } string text = string.Join(";", new int[6] { num4, Lent ? 1 : 0, (Lent && outcome != Outcome.Died) ? num : 0, num5, flag ? 1 : 0, flag2 ? 1 : 0 }.Select((int v) => v.ToString(CultureInfo.InvariantCulture))) + ";" + string.Join(",", list2); string text2 = Words.Prize(text); int num7 = num4 + ((Lent && outcome != Outcome.Died) ? num : 0) + _kills * 5 + (flag ? 150 : 0) + Mathf.RoundToInt(_peak) + Round * 20; string said = ((Kind != KindOf.Road) ? Words.Line((Kind == KindOf.Endless) ? "arena_run_endless" : ((Kind == KindOf.Trial) ? "arena_run_trial" : "arena_run_champion"), Words.Land(Tier), Round) : (flag ? Words.Line("arena_run_road_end") : Words.Line("arena_run_road", Words.Land(Tier), Round, Rounds))); bool flag3 = (_crowned = outcome != Outcome.Aborted && outcome != Outcome.CalledOff && Ladder.Enter(KindWord(Kind), player.GetPlayerName(), said, num7, _look)); string text3 = (flag3 ? Words.Then("-", Words.Line("arena_call_new_champion_" + KindWord(Kind))) : ""); if (flag3) { Net.Sound("roar"); } string sub = Words.Line("arena_call_half_purse", text2); switch (outcome) { case Outcome.Win: Net.Shout(Words.Line("arena_call_victory"), Words.Then(Lines.Victory(), text2, text3), 7f); break; case Outcome.CashOut: Net.Shout(Words.Line("arena_call_cash_out"), Words.Then(text2, text3), 6f); break; case Outcome.Died: Net.Shout(Words.Line("arena_call_fallen"), Words.Line(Lent ? "arena_call_fallen_lent" : "arena_call_fallen_own"), 7f); break; case Outcome.TimeUp: Net.Shout(Words.Line("arena_call_time"), sub, 5f); break; case Outcome.LeftRing: Net.Shout(Words.Line("arena_call_left_ring"), sub, 5f); break; case Outcome.Yield: Net.Shout(Words.Line("arena_call_yield"), sub, 5f); break; case Outcome.Carried: Net.Shout(Words.Line("arena_call_carried"), sub, 5f); break; case Outcome.CalledOff: Net.Shout(Words.Line("arena_call_called_off"), Words.Line("arena_call_no_one", text2), 5f); break; } if (outcome != Outcome.Aborted && outcome != Outcome.Died && !_toChest) { ((Character)player).Message((MessageType)2, Translations.T("arena_prize", PrizeText(text)), 0, (Sprite)null, false); } Plugin.Log.LogInfo((object)$"Contest ended: {outcome}, {_kills} kills, prize {text}, score {num7}"); void Hand(string prefab, int amount) { if (_toChest) { PrizeItems.Add((prefab, amount, 1, null)); } else { Give(prefab, amount, player); } } } internal static string PrizeText(string data) { string[] array = data.Split(new char[1] { ';' }); if (array.Length < 7) { return data; } int[] array2 = new int[6]; for (int i = 0; i < 6; i++) { int.TryParse(array[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out array2[i]); } bool flag = array2[1] == 1; bool flag2 = array2[4] == 1; bool flag3 = array2[5] == 1; List<string> list = new List<string>(); if (array2[0] > 0) { list.Add(Translations.T(flag ? "arena_prize_coins_win" : "arena_coins", array2[0])); } if (array2[2] > 0) { list.Add(Translations.T("arena_prize_picked_up", array2[2])); } foreach (var item in Counted(array[6])) { list.Add(item.Prefab.StartsWith("Trophy") ? ItemName(item.Prefab) : Translations.T("arena_prize_item", item.Amount, ItemName(item.Prefab))); } if (array2[3] > 0) { list.Add(Translations.T(flag2 ? "arena_prize_stake_doubled" : "arena_prize_stake_back", array2[3])); } if (flag3) { list.Add(Translations.T("arena_prize_daily")); } if (list.Count <= 0) { return Translations.T("arena_prize_nothing"); } return string.Join(", ", list); } internal static void Give(string prefab, int amount, Player player) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null || amount <= 0) { return; } int num = Mathf.Max(1, val2.m_itemData.m_shared.m_maxStackSize); Inventory inventory = ((Humanoid)player).GetInventory(); while (amount > 0) { int num2 = Mathf.Min(amount, num); amount -= num2; if (inventory.CanAddItem(val, num2)) { inventory.AddItem(val, num2); } else { Object.Instantiate<GameObject>(val, ((Component)player).transform.position + Vector3.up, Quaternion.identity).GetComponent<ItemDrop>().SetStack(num2); } } } } internal static class Guard { private static float _graceUntil; private static float _next; internal static void Grace(float seconds) { _graceUntil = Mathf.Max(_graceUntil, Time.time + seconds); } internal static void Tick() { //IL_006c: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00ea: Unknown result type (might be due to invalid IL or missing references) if (!(Time.time < _next)) { _next = Time.time + 0.5f; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && !((Character)localPlayer).IsTeleporting() && Site.Known && Scenery.Built && !Contest.Active && !Duel.Active && !(Time.time < _graceUntil) && Site.OnFloor(((Component)localPlayer).transform.position, -0.5f)) { Vector3 val = Site.World(Layout.Arrival.Pos + new Vector3(0f, 0.3f, 3f)); val.y = Mathf.Max(val.y, Site.Ground(val, Site.Origin.y) + 0.3f); ((Character)localPlayer).TeleportTo(val, Site.Turn * Quaternion.Euler(0f, 180f, 0f), false); ((Character)localPlayer).Message((MessageType)2, Translations.T("arena_guards"), 0, (Sprite)null, false); Plugin.Log.LogInfo((object)"Someone on the fighting floor without a challenge was shown out to the forecourt"); } } } } internal static class Lines { private static string One(string key, params object[] args) { return Words.Line(key + "_" + Random.Range(1, 5), args); } internal static string Welcome(string name) { return One("arena_welcome", name); } internal static string RoundCall(int count) { return One("arena_round_call", count); } internal static string ChampionDown() { return One("arena_champion_down"); } internal static string Victory() { return One("arena_victory_line"); } } internal static class Crowd { private sealed class Spec { public GameObject Go; public Vector3 At; public float Angle; public float Next; public bool Sitting; } private static readonly List<Spec> Specs = new List<Spec>(); private static GameObject _root; private static float _lastAction; private static float _lastBoo; private static float _waveAt; private static float _waveAngle; private static float _loudSince; private static float _nextBuild; private static bool _open; private static int _building; internal static float Favour { get; private set; } internal static float Excitement { get; private set; } internal static bool IsOpen => _open; internal static string Mood => Translations.T((Favour < 15f) ? "arena_mood_bored" : ((Favour < 35f) ? "arena_mood_restless" : ((Favour < 55f) ? "arena_mood_watching" : ((Favour < 75f) ? "arena_mood_excited" : ((Favour < 90f) ? "arena_mood_roaring" : "arena_mood_ecstatic"))))); internal static void Open() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown Close(bow: false); _open = true; Favour = 25f; Excitement = 0.25f; _lastAction = Time.time; _waveAt = 0f; _loudSince = 0f; if (Plugin.Spectators.Value && Site.Known && (Object)(object)Scenery.Root != (Object)null) { _root = new GameObject("ArenaCrowd"); _building = 0; } } internal static void Close(bool bow) { _open = false; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; Specs.Clear(); } internal static void Clear() { Close(bow: false); Sound.Clear(); } private static void FillSome() { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || Time.time < _nextBuild) { return; } int num = Mathf.RoundToInt((float)Layout.Seats.Count * Mathf.Clamp01(Plugin.CrowdSize.Value / 100f)); if (Specs.Count >= num || _building >= Layout.Seats.Count) { return; } _nextBuild = Time.time + 0.05f; int num2 = Mathf.Max(1, Layout.Seats.Count / Mathf.Max(1, num)); for (int i = 0; i < 3; i++) { if (Specs.Count >= num) { break; } if (_building >= Layout.Seats.Count) { break; } Random random = new Random(_building * 7919 + 13); int index = (_building * num2 + _building / Mathf.Max(1, Layout.Seats.Count / num2)) % Layout.Seats.Count; Layout.Mark mark = Layout.Seats[index]; _building++; Vector3 val = mark.Pos + new Vector3((float)(random.NextDouble() - 0.5) * 0.4f, 0f, 0f); Vector3 val2 = Site.World(val); Vector3 val3 = Site.Centre - val2; val3.y = 0f; GameObject val4 = Figures.Make(_root.transform, val2, Quaternion.LookRotation(val3), Figures.Spectator(random), collider: false); if ((Object)(object)val4 == (Object)null) { break; } Behaviour[] componentsInChildren = val4.GetComponentsInChildren<Behaviour>(true); foreach (Behaviour val5 in componentsInChildren) { if ((Object)(object)val5 != (Object)null && ((object)val5).GetType().Name.Contains("MagicaCloth")) { val5.enabled = false; } } Spec spec = new Spec { Go = val4, At = val2, Angle = Mathf.Atan2(val.x, val.z), Next = Time.time + (float)random.NextDouble() * 4f }; if (random.NextDouble() < 0.45) { spec.Sitting = true; Figures.Hold(val4, "sit", on: true); } Specs.Add(spec); } } internal static void Tick(float dt) { //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) Sound.Tick(_open, Excitement); if (!_open) { Excitement = Mathf.MoveTowards(Excitement, 0f, dt * 0.2f); return; } FillSome(); float num = Mathf.Clamp01(0.2f + Favour / 140f + ((Time.time - _lastAction < 3f) ? 0.35f : 0f)); Excitement = Mathf.MoveTowards(Excitement, num, dt * ((num > Excitement) ? 1.4f : 0.3f)); if (Contest.Fighting && Time.time - _lastAction > 16f) { Favour = Mathf.Max(0f, Favour - dt * 0.6f); if (Favour < 10f && Time.time - _lastBoo > 18f) { _lastBoo = Time.time; Boo(); Hud.Call(Translations.T("arena_call_boo"), Translations.T("arena_call_boo_sub"), big: false); } } Favours.Tick(); if (Excitement > 0.72f) { if (_loudSince == 0f) { _loudSince = Time.time; } } else { _loudSince = 0f; } if (_loudSince > 0f && Time.time - _loudSince > 3f && _waveAt == 0f) { _waveAt = Time.time; _waveAngle = Random.value * (float)Math.PI * 2f; } float num2 = ((_waveAt > 0f) ? (_waveAngle + (Time.time - _waveAt) * 1.8f) : (-100f)); if (_waveAt > 0f && Time.time - _waveAt > 3.4906588f) { _waveAt = 0f; } Player localPlayer = Player.m_localPlayer; Vector3 val = (((Object)(object)localPlayer != (Object)null && Site.OnFloor(((Component)localPlayer).transform.position, 2f)) ? ((Component)localPlayer).transform.position : Site.Centre); bool flag = Excitement > 0.5f; Vector3 val2 = default(Vector3); foreach (Spec spec in Specs) { if ((Object)(object)spec.Go == (Object)null) { continue; } ((Vector3)(ref val2))..ctor(val.x - spec.At.x, 0f, val.z - spec.At.z); if (((Vector3)(ref val2)).sqrMagnitude > 0.01f) { spec.Go.transform.rotation = Quaternion.Slerp(spec.Go.transform.rotation, Quaternion.LookRotation(val2, Vector3.up), dt * 1.5f); } if (spec.Sitting && flag) { spec.Sitting = false; Figures.Hold(spec.Go, "sit", on: false); spec.Next = Time.time + Random.Range(0.2f, 1.5f); } else if (!spec.Sitting && !flag && Random.value < dt * 0.02f) { spec.Sitting = true; Figures.Hold(spec.Go, "sit", on: true); } if (_waveAt > 0f && Mathf.Abs(Mathf.DeltaAngle(spec.Angle * 57.29578f, num2 * 57.29578f)) < 10f && Time.time > spec.Next) { spec.Next = Time.time + 2.5f; Figures.Emote(spec.Go, "cheer"); } else if (!spec.Sitting && Time.time > spec.Next && Random.value < 0.25f + 0.6f * Excitement) { spec.Next = Time.time + Random.Range(3f, 9f) * (1.4f - Excitement); if (Excitement > 0.35f) { Figures.Emote(spec.Go, Pick("cheer", "cheer", "roar", "toast", "flex", "challenge", "point", "thumbsup")); } } } } private static string Pick(params string[] list) { return list[Random.Range(0, list.Length)]; } private static void React(float share, params string[] emotes) { foreach (Spec spec in Specs) { if (!((Object)(object)spec.Go == (Object)null) && !(Random.value > share)) { if (spec.Sitting) { spec.Sitting = false; Figures.Hold(spec.Go, "sit", on: false); } spec.Next = Time.time + Random.Range(0f, 0.6f); Figures.Emote(spec.Go, emotes[Random.Range(0, emotes.Length)]); } } } internal static bool Throw(string item, int amount, Action<ItemDrop> setup = null) { //IL_00c1: 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_00c6: 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) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || Layout.Seats.Count == 0) { return false; } GameObject val = ((item != null) ? ZNetScene.instance.GetPrefab(item) : null); if ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent<ItemDrop>() == (Object)null) { return false; } Spec spec = ((Specs.Count > 0) ? Specs[Random.Range(0, Specs.Count)] : null); if ((Object)(object)spec?.Go != (Object)null) { Figures.Emote(spec.Go, "wave"); } Vector3 val2 = (spec?.At ?? Site.World(Layout.Seats[Random.Range(0, Layout.Seats.Count)].Pos)) + Vector3.up * 2f; Vector3 val3 = ((Component)localPlayer).transform.position + new Vector3(Random.Range(-2f, 2f), 0f, Random.Range(-2f, 2f)); GameObject val4 = Object.Instantiate<GameObject>(val, val2, Quaternion.identity); ItemDrop component = val4.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { setup?.Invoke(component); if (!Kit.IsLoan(component.m_itemData) && !Kit.Keeps(item, Contest.Tier)) { component.m_itemData.m_customData["dh_arena_loan"] = "gift"; } component.SetStack(Mathf.Max(1, amount)); } Rigidbody component2 = val4.GetComponent<Rigidbody>(); if ((Object)(object)component2 != (Object)null) { Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(val3.x - val2.x, 0f, val3.z - val2.z); float num = Mathf.Clamp(((Vector3)(ref val5)).magnitude / 9f, 0.8f, 1.8f); Vector3 linearVelocity = val5 / num; linearVelocity.y = (val3.y - val2.y) / num + 0.5f * (0f - Physics.gravity.y) * num; component2.linearVelocity = linearVelocity; } Cheer(); return true; } internal static void Mirror(string emote) { if (emote == "laugh") { Sound.Boo(); React(0.5f, "laugh", "point"); } else { Sound.Cheer(); React(0.55f, emote, emote, "cheer"); } } internal static void Gain(float amount, bool cheer) { Favour = Mathf.Clamp(Favour + amount, 0f, 100f); _lastAction = Time.time; if (cheer) { Cheer(); } } internal static void Set(float favour) { Favour = Mathf.Clamp(favour, 0f, 100f); } internal static void Hurt(float amount) { Favour = Mathf.Max(0f, Favour - amount); } internal static void Play(string name) { switch (name) { case "cheer": Cheer(); break; case "roar": Roar(); break; case "boo": Boo(); break; case "applause": Applause(); break; case "gong": Sound.Gong(); break; case "horn": Sound.Chant(); React(0.7f, "cheer", "roar", "toast"); break; } } internal static void Celebrate() { Favour = 100f; Excitement = 1f; _lastAction = Time.time; foreach (Spec spec in Specs) { if ((Object)(object)spec.Go != (Object)null && spec.Sitting) { spec.Sitting = false; Figures.Hold(spec.Go, "sit", on: false); } } React(1f, "cheer", "roar", "toast", "flex", "challenge"); _waveAt = Time.time; _waveAngle = Random.value * (float)Math.PI * 2f; _loudSince = Time.time; } internal static void Cheer() { Sound.Cheer(); React(0.35f, "cheer", "roar", "flex", "toast"); } internal static void Roar() { Sound.Roar(); React(0.8f, "cheer", "roar", "challenge", "toast", "flex"); } internal static void Boo() { Sound.Boo(); React(0.3f, "nonono", "laugh", "point"); } internal static void Applause() { Sound.Applause(); React(0.4f, "cheer", "thumbsup"); } internal static void Gong() { Sound.Gong(); } internal static void Horn() { Play("horn"); } } internal static class Duel { private enum PhaseKind { None, Walking, Countdown, Fighting } private const string RpcChallenge = "DHArenaChallenge"; private const string RpcAnswer = "DHArenaAnswer"; private const string RpcEnd = "DHArenaEnd"; private static PhaseKind _phase; private static long _opponent; private static string _opponentName = ""; private static int _wager; private static int _count; private static Vector3 _at; private static float _timer; private static float _outside; private static float _missing; private static float _closeAt; private static bool _prevPvp; private static bool _ending; private static bool _placed; private static bool _pvpSet; private const float Apart = 8f; private static long _inFrom; private static long _outTo; private static string _inName = ""; private static int _inWager; private static int _outWager; private static Vector3 _inAt; private static Vector3 _outAt; private static float _inUntil; private static float _outUntil; private static ZRoutedRpc _registeredOn; private static int _awakeFrame = -100; internal static bool Active => _phase != PhaseKind.None; internal static bool Fighting => _phase == PhaseKind.Fighting; internal static string OpponentName => _opponentName; internal static int Wager => _wager; internal static Vector3 Centre => Site.Centre; internal static Player Opponent => ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => (Object)(object)p != (Object)null && ((Character)p).GetOwner() == _opponent)); internal static bool HasIncoming { get { if (_inFrom != 0L) { return Time.unscaledTime < _inUntil; } return false; } } internal static string IncomingName => _inName; internal static int IncomingWager => _inWager; private static long MyId => ZDOMan.GetSessionID(); internal static void Init() { _awakeFrame = Time.frameCount; } internal static bool Involves(long peer) { if (peer != 0L) { if (!Active || peer != _opponent) { if (peer == _outTo) { return Time.unscaledTime < _outUntil; } return false; } return true; } return false; } private static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance == null) { _registeredOn = null; } else if (Time.frameCount > _awakeFrame + 2 && instance != _registeredOn) { _registeredOn = instance; Unregister(); instance.Register<ZPackage>("DHArenaChallenge", (Action<long, ZPackage>)OnChallenge); instance.Register<ZPackage>("DHArenaAnswer", (Action<long, ZPackage>)OnAnswer); instance.Register<ZPackage>("DHArenaEnd", (Action<long, ZPackage>)OnEnd); } } internal static void Unregister() { if (ZRoutedRpc.instance != null && AccessTools.Field(typeof(ZRoutedRpc), "m_functions").GetValue(ZRoutedRpc.instance) is IDictionary dictionary) { string[] array = new string[3] { "DHArenaChallenge", "DHArenaAnswer", "DHArenaEnd" }; foreach (string text in array) { dictionary.Remove(StringExtensionMethods.GetStableHashCode(text)); } } } private static void Send(long to, string rpc, ZPackage pkg) { if (ZRoutedRpc.instance == null) { return; } try { ZRoutedRpc.instance.InvokeRoutedRPC(to, rpc, new object[1] { pkg }); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Arena duel message failed: " + ex.Message)); } } private static string NameOf(long owner) { Player val = ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player x) => (Object)(object)x != (Object)null && ((Character)x).GetOwner() == owner)); if (!((Object)(object)val != (Object)null)) { return Translations.T("arena_your_opponent"); } return val.GetPlayerName(); } internal static string Challenge(Player other, int wager, Vector3 at) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)other == (Object)null) { return Translations.T("arena_not_now"); } if (Active || Contest.Active) { return Translations.T("arena_already_fighting"); } if (Net.RemoteFight) { return Translations.T("arena_busy_wait_ring", Net.BusyText); } if (((Humanoid)localPlayer).GetInventory().CountItems("$item_coins", -1, true) < wager) { return Translations.T("arena_no_coins_wager"); } _outTo = ((Character)other).GetOwner(); _outWager = wager; _outAt = at; _outUntil = Time.unscaledTime + 30f; ZPackage val = new ZPackage(); val.Write(wager); val.Write(localPlayer.GetPlayerName()); val.Write(at); Send(_outTo, "DHArenaChallenge", val); return null; } private static void OnChallenge(long sender, ZPackage pkg) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) int inWager = pkg.ReadInt(); string text = pkg.ReadString(); Vector3 inAt = pkg.ReadVector3(); if (!((Object)(object)Player.m_localPlayer == (Object)null)) { if (Active || Contest.Active || HasIncoming || Net.RemoteFight) { Reply(sender, accept: false); return; } _inFrom = sender; _inName = text; _inWager = inWager; _inAt = inAt; _inUntil = Time.unscaledTime + 30f; ((Character)Player.m_localPlayer).Message((MessageType)2, Translations.T("arena_challenges_you", text), 0, (Sprite)null, false); Window.Open(Window.Context.Master, null, 1); } } private static void Reply(long to, bool accept) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(accept); Send(to, "DHArenaAnswer", val); } internal static string Accept() { //IL_009d: 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) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !HasIncoming) { return Translations.T("arena_challenge_expired"); } if (Active || Contest.Active) { return Translations.T("arena_already_fighting"); } if (Net.RemoteFight) { Decline(); return Translations.T("arena_busy_taken", Net.BusyText); } if (((Humanoid)localPlayer).GetInventory().CountItems("$item_coins", -1, true) < _inWager) { Decline(); return Translations.T("arena_no_coins_wager"); } if (Travel.Distance(((Component)localPlayer).transform.position) > 90f) { return Translations.T("arena_come_first"); } long inFrom = _inFrom; string inName = _inName; int inWager = _inWager; Vector3 inAt = _inAt; _inFrom = 0L; Reply(inFrom, accept: true); Begin(inFrom, inName, inWager, inAt); Window.Close(); return null; } internal static void Decline() { if (_inFrom != 0L) { Reply(_inFrom, accept: false); } _inFrom = 0L; } private static void OnAnswer(long sender, ZPackage pkg) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) bool flag = pkg.ReadBool(); Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && sender == _outTo && !(Time.unscaledTime > _outUntil)) { _outTo = 0L; if (!flag) { Hud.Say(Translations.T("arena_challenge_refused", NameOf(sender))); } else if (Active || Contest.Active || Net.RemoteFight || ((Humanoid)localPlayer).GetInventory().CountItems("$item_coins", -1, true) < _outWager) { End(sender, theyWin: false, "cancel"); } else { Begin(sender, NameOf(sender), _outWager, _outAt); } } } private static void Begin(long opponent, string name, int wager, Vector3 at) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { if (wager > 0) { ((Humanoid)localPlayer).GetInventory().RemoveItem("$item_coins", wager, -1, true); } _opponent = opponent; _opponentName = name; _wager = wager; _at = at; _phase = PhaseKind.Walking; _timer = 90f; _count = 6; _outside = 0f; _missing = 0f; _ending = false; _closeAt = 0f; _placed = false; ((Character)localPlayer).Heal(((Character)localPlayer).GetMaxHealth(), true); Crowd.Open(); Crowd.Gong(); Scenery.OpenGate(Scenery.MainGrate, 90f); Net.Door(90f); Hud.Shout(Translations.T("arena_call_duel"), (wager > 0) ? Translations.T("arena_duel_begin_wager", name, wager) : Translations.T("arena_duel_begin", name), 5f); } } internal static void Tick(float dt) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) Register(); if (_closeAt > 0f && Time.time >= _closeAt) { _closeAt = 0f; if (!Contest.Active) { Crowd.Close(bow: true); } } if (!Active) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (_phase == PhaseKind.Walking) { _timer -= dt; Player opponent = Opponent; if (!_placed && Site.OnFloor(((Component)localPlayer).transform.position, -1f)) { _placed = true; Place(localPlayer); Hud.Say(Translations.T("arena_duel_wait", _opponentName)); } if (_placed) { Hold(localPlayer); } if (_placed && (Object)(object)opponent != (Object)null && Site.OnFloor(((Component)opponent).transform.position, -1f)) { Scenery.CloseGate(Scenery.MainGrate); Net.Door(0f); _phase = PhaseKind.Countdown; _timer = 5.5f; _count = 6; Hud.Shout(Translations.T("arena_call_duel"), (_wager > 0) ? Translations.T("arena_duel_vs_pot", _opponentName, _wager * 2) : Translations.T("arena_duel_vs", _opponentName), 3.5f); Crowd.Gong(); } else if (_timer <= 0f) { if (_wager > 0) { Contest.Give("Coins", _wager, localPlayer); } End(_opponent, theyWin: false, "cancel"); Finish(null, Translations.T("arena_duel_timeout")); } return; } if (_phase == PhaseKind.Countdown) { Hold(localPlayer); _timer -= dt; int num = Mathf.CeilToInt(_timer); if (num < _count && num >= 1 && num <= 5) { _count = num; Hud.Count(num.ToString()); } if (_timer <= 0f) { _prevPvp = ((Character)localPlayer).IsPVPEnabled(); _pvpSet = true; localPlayer.SetPVP(true); _phase = PhaseKind.Fighting; Hud.Count(Translations.T("arena_fight")); Crowd.Cheer(); } return; } if (!((Character)localPlayer).IsPVPEnabled()) { localPlayer.SetPVP(true); Hud.Say(Translations.T("arena_pvp_stays")); } if (!Player.GetAllPlayers().Any((Player p) => (Object)(object)p != (Object)null && ((Character)p).GetOwner() == _opponent)) { _missing += dt; } else { _missing = 0f; } if (_missing > 8f) { if (_wager > 0) { Contest.Give("Coins", _wager, localPlayer); } Finish(null, Translations.T("arena_duel_gone")); } else if (!Site.OnFloor(((Component)localPlayer).transform.position, 1.5f)) { _outside += dt; if (_outside > 6f) { End(_opponent, theyWin: true, "forfeit"); Finish(false, Translations.T("arena_duel_left")); } } else { _outside = Mathf.Max(0f, _outside - dt); } } private static Vector3 Mark(out Quaternion facing) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) float num = ((MyId < _opponent) ? (-1f) : 1f); float num2 = num * 8f; facing = Site.Turn * Quaternion.LookRotation(new Vector3(0f - num, 0f, 0f)); return Site.World(new Vector3(num2, Layout.FloorHeight(num2, 0f) + 0.15f, 0f)); } private static void Place(Player me) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) Quaternion facing; Vector3 val = Mark(out facing); val.y = Site.Ground(val, val.y) + 0.15f; ((Component)me).transform.SetPositionAndRotation(val, facing); Rigidbody component = ((Component)me).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.position = val; component.linearVelocity = Vector3.zero; } ((Character)me).SetLookDir(facing * Vector3.forward, 0f); Fx.SpawnPuff(val); Crowd.Cheer(); } private static void Hold(Player me) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Quaternion facing; Vector3 val = Mark(out facing); Vector3 val2 = ((Component)me).transform.position - val; val2.y = 0f; if (((Vector3)(ref val2)).magnitude > 1.5f) { Place(me); } } internal static void Lose() { if (_phase == PhaseKind.Fighting && !_ending) { _ending = true; End(_opponent, theyWin: true, "beaten"); Finish(false, Translations.T("arena_duel_beaten")); } } private static void End(long to, bool theyWin, string reason) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(theyWin); val.Write(reason); Send(to, "DHArenaEnd", val); } private static void OnEnd(long sender, ZPackage pkg) { bool flag = pkg.ReadBool(); string text = pkg.ReadString(); if (!Active || sender != _opponent) { return; } if (text == "cancel") { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && _wager > 0) { Contest.Give("Coins", _wager, localPlayer); } Finish(null, Translations.T("arena_duel_called_off")); } else { _ending = true; Finish(flag, flag ? Translations.T((text == "forfeit") ? "arena_duel_they_left" : "arena_duel_they_beaten", _opponentName) : Translations.T("arena_duel_beaten")); } } private static void Finish(bool? win, string why) { Player localPlayer = Player.m_localPlayer; bool flag = _phase == PhaseKind.Fighting; _phase = PhaseKind.None; Scenery.OpenGate(Scenery.MainGrate, 30f); Net.Door(45f); Guard.Grace(60f); if ((Object)(object)localPlayer != (Object)null) { if (_pvpSet) { localPlayer.SetPVP(_prevPvp); } _pvpSet = false; ((Character)localPlayer).Heal(((Character)localPlayer).GetMaxHealth(), true); if (win == true) { int num = _wager * 2; int num2 = num / 10; if (num - num2 > 0) { Contest.Give("Coins", num - num2, localPlayer); } Ladder.Add("duelwins", 1); Hud.Shout(Translations.T("arena_call_you_win"), why + ((num > 0) ? (" - " + Translations.T("arena_coins", num - num2)) : ""), 5f); Crowd.Roar(); Crowd.Horn(); } else if (win == false) { Ladder.Add("duellosses", 1); Hud.Shout(Translations.T("arena_call_defeated"), why); Crowd.Boo(); } else { Hud.Shout(Translations.T("arena_call_duel_off"), why, 3f); } } _closeAt = Time.time + 6f; } internal static void Abort(bool tell) { if (Active) { Player localPlayer = Player.m_localPlayer; if (tell) { End(_opponent, theyWin: true, "forfeit"); } if ((Object)(object)localPlayer != (Object)null && _pvpSet) { localPlayer.SetPVP(_prevPvp); } _pvpSet = false; _phase = PhaseKind.None; } } } internal static class Favours { private enum Demand { None, Emote, Kill, Parry, Untouched } private static float _nextGift; private static bool _pitied; private static int _steelLand = -1; private static readonly string[] HealthMeads = new string[7] { "MeadHealthMinor", "MeadHealthMinor", "MeadHealthMinor", "MeadHealthMedium", "MeadHealthMedium", "MeadHealthMajor", "MeadHealthMajor" }; private static readonly string[] StaminaMeads = new string[7] { "MeadStaminaMinor", "MeadStaminaMin