Decompiled source of SafehouseBlackjack v0.5.1
WhiteKnuckleBlackjack.dll
Decompiled a month 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using WhiteKnuckleBlackjack.Assets; using WhiteKnuckleBlackjack.Rules; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Battery_Boy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) 2026 Battery_Boy")] [assembly: AssemblyDescription("A White Knuckle blackjack machine built entirely around in-game assets.")] [assembly: AssemblyFileVersion("0.5.1.0")] [assembly: AssemblyInformationalVersion("0.5.1")] [assembly: AssemblyProduct("Safehouse Blackjack")] [assembly: AssemblyTitle("WhiteKnuckleBlackjack")] [assembly: AssemblyVersion("0.5.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 WhiteKnuckleBlackjack { internal sealed class BlackjackAnnouncementPlayer : MonoBehaviour { private readonly List<AudioClip> _clips = new List<AudioClip>(); private readonly List<AudioClip> _winClips = new List<AudioClip>(); private readonly List<int> _shuffleBag = new List<int>(); private readonly List<int> _winShuffleBag = new List<int>(); private AudioSource? _source; private ManualLogSource? _log; private float _chance; private int _lastClip = -1; private int _lastWinClip = -1; private bool _announcementPending; internal void Configure(int chancePercent, ManualLogSource log) { _chance = (float)Mathf.Clamp(chancePercent, 0, 100) / 100f; _log = log; _source = ((Component)this).gameObject.AddComponent<AudioSource>(); _source.playOnAwake = false; _source.loop = false; _source.spatialBlend = 0f; _source.volume = 1f; string directory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty, "PA"); ((MonoBehaviour)this).StartCoroutine(LoadAudio(directory)); } internal void QueueAfterRound(RoundOutcome outcome) { bool flag = outcome == RoundOutcome.PlayerWin || outcome == RoundOutcome.PlayerBlackjack; List<AudioClip> list = ((flag && _winClips.Count > 0) ? _winClips : _clips); if (!_announcementPending && !((Object)(object)_source == (Object)null) && list.Count != 0 && !(Random.value > _chance)) { int index = ((flag && list == _winClips) ? TakeShuffledIndex(list, _winShuffleBag, ref _lastWinClip) : TakeShuffledIndex(list, _shuffleBag, ref _lastClip)); _announcementPending = true; ((MonoBehaviour)this).StartCoroutine(PlayAfterDelay(Random.Range(0.65f, 2.25f), list[index])); } } private IEnumerator LoadAudio(string directory) { if (!Directory.Exists(directory)) { ManualLogSource? log = _log; if (log != null) { log.LogWarning((object)("Blackjack PA directory was not found: " + directory)); } yield break; } string[] array = Directory.GetFiles(directory, "*.mp3", SearchOption.TopDirectoryOnly).OrderBy<string, string>((string result) => result, StringComparer.OrdinalIgnoreCase).ToArray(); string[] array2 = array; foreach (string path in array2) { string absoluteUri = new Uri(path).AbsoluteUri; UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)13); try { yield return request.SendWebRequest(); if ((int)request.result != 1) { ManualLogSource? log2 = _log; if (log2 != null) { log2.LogWarning((object)("Could not load blackjack PA clip " + Path.GetFileName(path) + ": " + request.error)); } continue; } AudioClip content = DownloadHandlerAudioClip.GetContent(request); if (!((Object)(object)content == (Object)null)) { ((Object)content).name = Path.GetFileNameWithoutExtension(path); if (((Object)content).name.StartsWith("Blackjack_Win_", StringComparison.OrdinalIgnoreCase)) { _winClips.Add(content); } else { _clips.Add(content); } } } finally { ((IDisposable)request)?.Dispose(); } } ManualLogSource? log3 = _log; if (log3 != null) { log3.LogInfo((object)("Blackjack PA clips loaded: general=" + _clips.Count + ", win-only=" + _winClips.Count)); } } private IEnumerator PlayAfterDelay(float delay, AudioClip clip) { yield return (object)new WaitForSecondsRealtime(delay); _announcementPending = false; if (!((Object)(object)_source == (Object)null) && !_source.isPlaying && !((Object)(object)clip == (Object)null)) { _source.PlayOneShot(clip); ManualLogSource? log = _log; if (log != null) { log.LogInfo((object)("Blackjack PA announcement=" + ((Object)clip).name)); } } } private static int TakeShuffledIndex(List<AudioClip> clips, List<int> shuffleBag, ref int lastClip) { if (shuffleBag.Count == 0) { for (int i = 0; i < clips.Count; i++) { shuffleBag.Add(i); } for (int num = shuffleBag.Count - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); List<int> list = shuffleBag; int index = num; int index2 = num2; int value = shuffleBag[num2]; int value2 = shuffleBag[num]; list[index] = value; shuffleBag[index2] = value2; } if (shuffleBag.Count > 1 && shuffleBag[shuffleBag.Count - 1] == lastClip) { int num3 = Random.Range(0, shuffleBag.Count - 1); List<int> list = shuffleBag; int index2 = num3; int index = shuffleBag.Count - 1; int value2 = shuffleBag[shuffleBag.Count - 1]; int value = shuffleBag[num3]; list[index2] = value2; shuffleBag[index] = value; } } int index3 = shuffleBag.Count - 1; int num4 = shuffleBag[index3]; shuffleBag.RemoveAt(index3); lastClip = num4; return num4; } } internal sealed class BlackjackController : IDisposable { private readonly ModConfig _config; private readonly ManualLogSource _log; private readonly BlackjackGame _game; private readonly Wallet _wallet; private bool _payoutApplied; private int _observedWalletBalance; internal int SelectedBet { get; private set; } internal int WalletBalance => _wallet.Balance; internal bool CanDouble { get { if (_game.Phase == RoundPhase.PlayerTurn && _game.Player.Cards.Count == 2) { return WalletBalance >= _game.Bet; } return false; } } internal string StatusLine => _game.Message; internal string PlayerDisplay { get { if (_game.Player.Cards.Count != 0) { return _game.Player.ToString(); } return "--"; } } internal string PlayerHandReadout => HandReadout.Cards(_game.Player); internal string PlayerTotalReadout => HandReadout.Total(_game.Player); internal string DealerHandReadout => HandReadout.Cards(_game.Dealer, _game.HoleCardHidden ? 1 : (-1)); internal string DealerTotalReadout => HandReadout.Total(_game.Dealer, _game.HoleCardHidden ? 1 : (-1)); internal string DealerDisplay { get { if (_game.Dealer.Cards.Count == 0) { return "--"; } if (!_game.HoleCardHidden) { return _game.Dealer.ToString(); } Card card = _game.Dealer.Cards[0]; return card.ShortName + " ?? [" + card.HardValue + "+]"; } } internal Hand PlayerHand => _game.Player; internal Hand DealerHand => _game.Dealer; internal bool HideDealerHoleCard => _game.HoleCardHidden; internal RoundPhase Phase => _game.Phase; internal event Action? Changed; internal event Action<RoundOutcome>? RoundSettled; internal BlackjackController(ModConfig config, ManualLogSource log) { _config = config; _log = log; _wallet = new Wallet(config); _game = new BlackjackGame(config.DealerHitsSoft17.Value, Environment.TickCount); SelectedBet = ClampBet(config.MinimumBet.Value); _observedWalletBalance = _wallet.Balance; } internal void Tick() { bool flag = false; int balance = _wallet.Balance; if (balance != _observedWalletBalance) { _observedWalletBalance = balance; flag = true; } if (_game.Phase == RoundPhase.Betting) { int num = ClampBet(SelectedBet); if (num != SelectedBet) { SelectedBet = num; flag = true; } } if (flag) { RaiseChanged(); } } internal void IncreaseBet() { if (_game.Phase != RoundPhase.PlayerTurn && _game.Phase != RoundPhase.DealerTurn) { SelectedBet = ClampBet(SelectedBet + Math.Max(1, _config.BetStep.Value)); RaiseChanged(); } } internal void DecreaseBet() { if (_game.Phase != RoundPhase.PlayerTurn && _game.Phase != RoundPhase.DealerTurn) { SelectedBet = ClampBet(SelectedBet - Math.Max(1, _config.BetStep.Value)); RaiseChanged(); } } internal void DealOrNewRound() { if (_game.Phase == RoundPhase.PlayerTurn || _game.Phase == RoundPhase.DealerTurn) { return; } if (_game.Phase == RoundPhase.Settled) { _game.ReturnToBetting(); } SelectedBet = ClampBet(SelectedBet); if (SelectedBet <= 0 || !_wallet.TrySpend(SelectedBet)) { _log.LogMessage((object)"Blackjack: not enough roaches/chips for that wager."); RaiseChanged(); return; } _payoutApplied = false; if (!_game.StartRound(SelectedBet)) { _wallet.Add(SelectedBet); return; } ApplyPayoutIfSettled(); RaiseChanged(); } internal void Hit() { if (_game.Hit()) { ApplyPayoutIfSettled(); RaiseChanged(); } } internal void Stand() { if (_game.Stand()) { ApplyPayoutIfSettled(); RaiseChanged(); } } internal void DoubleDown() { if (!CanDouble) { return; } int bet = _game.Bet; if (_wallet.TrySpend(bet)) { if (!_game.DoubleDown()) { _wallet.Add(bet); return; } ApplyPayoutIfSettled(); RaiseChanged(); } } private void ApplyPayoutIfSettled() { if (_game.Phase == RoundPhase.Settled && !_payoutApplied) { _payoutApplied = true; int num = _game.Payout(); if (num > 0) { _wallet.Add(num); } this.RoundSettled?.Invoke(_game.Outcome); } } private int ClampBet(int value) { int val = Math.Max(Math.Max(1, _config.MinimumBet.Value), _config.MaximumBet.Value); int val2 = Math.Max(0, WalletBalance); return Math.Max(0, Math.Min(Math.Min(value, val), val2)); } private void RaiseChanged() { _observedWalletBalance = _wallet.Balance; this.Changed?.Invoke(); } public void Dispose() { } } internal sealed class Wallet { private readonly ModConfig _config; private int _practiceBalance; internal int Balance { get { try { return _config.Economy.Value switch { EconomyMode.RunRoaches => CL_GameManager.GetRoaches(false), EconomyMode.FacilityCredits => CL_GameManager.GetRoaches(true), _ => _practiceBalance, }; } catch { return _practiceBalance; } } } internal Wallet(ModConfig config) { _config = config; _practiceBalance = Math.Max(0, config.PracticeStartingChips.Value); } internal bool TrySpend(int amount) { if (amount <= 0 || Balance < amount) { return false; } Set(Balance - amount); return true; } internal void Add(int amount) { if (amount > 0) { Set(Balance + amount); } } private void Set(int value) { value = Math.Max(0, value); try { switch (_config.Economy.Value) { case EconomyMode.RunRoaches: CL_GameManager.SetRoaches(Math.Min(999, value), false); break; case EconomyMode.FacilityCredits: CL_GameManager.SetRoaches(Math.Min(9999, value), true); break; default: _practiceBalance = value; break; } } catch { _practiceBalance = value; } } } internal sealed class PhysicalTable : IDisposable { private sealed class CardVisual { internal const string HiddenDealerCardText = "Dealer card (hidden)"; internal readonly Card Card; internal readonly GameObject GameObject; private readonly TextMesh? _text; private readonly Item? _heldItemData; private bool _heldTextIsHidden; internal CardVisual(Card card, GameObject gameObject, TextMesh? text, Item? heldItemData, bool hidden) { Card = card; GameObject = gameObject; _text = text; _heldItemData = heldItemData; _heldTextIsHidden = hidden; } internal void UpdateLabel(bool hidden) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_text != (Object)null) { _text.text = (hidden ? "▥" : Card.ShortName); _text.color = (Color)((!hidden && (Card.Suit == 1 || Card.Suit == 2)) ? new Color(0.8f, 0.12f, 0.08f) : Color.black); } if (_heldItemData == null || _heldTextIsHidden == hidden) { return; } _heldTextIsHidden = hidden; string text = (hidden ? "Dealer card (hidden)" : CardHeldName(Card)); try { _heldItemData.SetFirstDataStringsofType("text", text); HandItem_Note[] array = Resources.FindObjectsOfTypeAll<HandItem_Note>(); foreach (HandItem_Note val in array) { if (!((Object)(object)val == (Object)null) && ((HandItem)val).item == _heldItemData && !((Object)(object)val.text == (Object)null)) { val.text.text = DarkMachineFunctions.ProcessText(text, true).TrimStart(); } } } catch { } } } private sealed class CounterDisplay { private readonly UT_RoachCounter? _native; private readonly NativeCounterTicker? _ticker; private readonly TextMesh? _fallbackText; private int _lastValue = int.MinValue; internal CounterDisplay(UT_RoachCounter? native, NativeCounterTicker? ticker, TextMesh? fallbackText) { _native = native; _ticker = ticker; _fallbackText = fallbackText; } internal void SetValue(int value) { int num = Math.Min(999, Math.Max(0, value)); if (num != _lastValue) { _lastValue = num; UT_RoachCounter? native = _native; if (native != null) { ((NumberCounter)native).SetDigits(num); } _ticker?.SetValue(num); if ((Object)(object)_fallbackText != (Object)null) { _fallbackText.text = num.ToString("000"); } } } } private readonly GameObject _root; private readonly BlackjackController _controller; private readonly AssetCatalog _assets; private readonly ManualLogSource _log; private readonly List<CardVisual> _dealerCardVisuals = new List<CardVisual>(); private readonly List<CardVisual> _playerCardVisuals = new List<CardVisual>(); private readonly List<Mesh> _generatedMeshes = new List<Mesh>(); private readonly List<ParticleSystem> _winConfetti = new List<ParticleSystem>(); private readonly List<AudioSource> _winSounds = new List<AudioSource>(); private readonly List<ParticleSystem> _lossParticles = new List<ParticleSystem>(); private AudioSource? _lossSound; private readonly CounterDisplay _walletCounter; private readonly CounterDisplay _betCounter; private readonly CL_Button? _hitButton; private readonly CL_Button? _standButton; private readonly CL_Button? _betDownButton; private readonly CL_Button? _betUpButton; private TextMesh? _playerHandReadout; private TextMesh? _playerTotalReadout; private TextMesh? _dealerHandReadout; private TextMesh? _dealerTotalReadout; private readonly bool _usesAuthoredRoomLocalTransform; internal bool IsAlive => (Object)(object)_root != (Object)null; internal bool IsEditing => false; internal bool IsAuthoredRoomLocalFor(Transform levelRoot) { if ((Object)(object)_root != (Object)null && _usesAuthoredRoomLocalTransform) { return (Object)(object)_root.transform.parent == (Object)(object)levelRoot; } return false; } private PhysicalTable(Transform levelRoot, BlackjackController controller, ModConfig config, ManualLogSource log, Vector3? fixedPosition = null, Quaternion? fixedRotation = null, bool fixedTransformIsLocal = false) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) _log = log; _controller = controller; _assets = AssetCatalog.Discover(levelRoot); _usesAuthoredRoomLocalTransform = fixedTransformIsLocal; _root = new GameObject("WK_Blackjack_Table"); try { _root.transform.SetParent(levelRoot, !fixedTransformIsLocal); if (fixedPosition.HasValue && fixedRotation.HasValue) { if (fixedTransformIsLocal) { _root.transform.localPosition = fixedPosition.Value; _root.transform.localRotation = fixedRotation.Value; _root.transform.localScale = Vector3.one; _log.LogInfo((object)"Applied exact Blender prefab-local transform without player or floor-ray adjustment."); } else { Vector3 value = fixedPosition.Value; float num = FindGroundY(value, value.y - 1.74f); _root.transform.position = new Vector3(value.x, num, value.z); _root.transform.rotation = fixedRotation.Value; _log.LogInfo((object)("Blender GROUND aligned to world floor Y=" + num.ToString("0.###"))); } } else { PlaceInFrontOfPlayer(_root.transform, config.TableOffset.Value); } BuildFurniture(); BuildDecorations(); BuildCelebrationShooters(); BuildLossEffect(); BuildHandDisplay(); BuildInstructionNote(); _walletCounter = CreateCounterDisplay("WK_Blackjack_WalletCounter", new string[3] { "WhiteKnuckleBlackjack.Assets.WagerOnesWheel.obj", "WhiteKnuckleBlackjack.Assets.WagerTensWheel.obj", "WhiteKnuckleBlackjack.Assets.WagerHundredsWheel.obj" }, (Vector3[])(object)new Vector3[3] { new Vector3(0.51472276f, 1.8156396f, -0.018863142f), new Vector3(0.7305726f, 1.8156396f, -0.018863142f), new Vector3(0.94642234f, 1.8156396f, -0.018863142f) }, new Vector3(0.64f, 1.8156396f, 0.40528f)); _betCounter = CreateCounterDisplay("WK_Blackjack_BetCounter", new string[3] { "WhiteKnuckleBlackjack.Assets.WalletOnesWheel.obj", "WhiteKnuckleBlackjack.Assets.WalletTensWheel.obj", "WhiteKnuckleBlackjack.Assets.WalletHundredsWheel.obj" }, (Vector3[])(object)new Vector3[3] { new Vector3(-0.92850775f, 1.8156396f, -0.015233129f), new Vector3(-0.7126579f, 1.8156396f, -0.015233129f), new Vector3(-0.49680817f, 1.8156396f, -0.015233129f) }, new Vector3(-0.64f, 1.8156396f, 0.40891f)); _hitButton = CreateButton("WK_Blackjack_Hit", "WhiteKnuckleBlackjack.Assets.HitButton.obj", new Vector3(-0.3999626f, 1.7712188f, 1.0282702f), new Vector3(0.2005618f, 0.1139842f, 0.22f), _assets.ActionButtonTemplate, delegate { HitOrDeal(controller); }); _standButton = CreateButton("WK_Blackjack_Stand", "WhiteKnuckleBlackjack.Assets.StandButton.obj", new Vector3(0.3981274f, 1.7712188f, 1.0191802f), new Vector3(0.2005618f, 0.1139842f, 0.22f), _assets.ActionButtonTemplate, controller.Stand); _betDownButton = CreateButton("WK_Blackjack_BetDown", "WhiteKnuckleBlackjack.Assets.BetDownButton.obj", new Vector3(-0.1470144f, 1.7686613f, 0.8662343f), new Vector3(0.22f, 0.1241184f, 0.22f), _assets.BetDownButtonTemplate, controller.DecreaseBet); _betUpButton = CreateButton("WK_Blackjack_BetUp", "WhiteKnuckleBlackjack.Assets.BetUpButton.obj", new Vector3(0.1429856f, 1.7686613f, 0.8662343f), new Vector3(0.22f, 0.1241184f, 0.22f), _assets.BetUpButtonTemplate, controller.IncreaseBet); _controller.RoundSettled += PlayRoundEffects; } catch { CleanupFailedConstruction(); throw; } } private void CleanupFailedConstruction() { _controller.RoundSettled -= PlayRoundEffects; if ((Object)(object)_root != (Object)null) { _root.SetActive(false); Object.Destroy((Object)(object)_root); } foreach (Mesh generatedMesh in _generatedMeshes) { if ((Object)(object)generatedMesh != (Object)null) { Object.Destroy((Object)(object)generatedMesh); } } _generatedMeshes.Clear(); } internal static PhysicalTable Create(Transform levelRoot, BlackjackController controller, ModConfig config, ManualLogSource log) { return new PhysicalTable(levelRoot, controller, config, log); } internal static PhysicalTable CreateAt(Transform levelRoot, Vector3 position, Quaternion rotation, BlackjackController controller, ModConfig config, ManualLogSource log) { //IL_0006: 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) return new PhysicalTable(levelRoot, controller, config, log, position, rotation); } internal static PhysicalTable CreateAtLocal(Transform levelRoot, Vector3 localPosition, Quaternion localRotation, BlackjackController controller, ModConfig config, ManualLogSource log) { //IL_0006: 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) return new PhysicalTable(levelRoot, controller, config, log, localPosition, localRotation, fixedTransformIsLocal: true); } internal void Render(BlackjackController controller) { if (!((Object)(object)_root == (Object)null)) { _walletCounter.SetValue(controller.WalletBalance); _betCounter.SetValue(controller.SelectedBet); SetButtonState(_hitButton, controller.Phase == RoundPhase.Betting || controller.Phase == RoundPhase.Settled || controller.Phase == RoundPhase.PlayerTurn); SetButtonState(_standButton, controller.Phase == RoundPhase.PlayerTurn); bool active = controller.Phase == RoundPhase.Betting || controller.Phase == RoundPhase.Settled; SetButtonState(_betDownButton, active); SetButtonState(_betUpButton, active); RenderHandDisplay(controller); RebuildCards(controller); } } private static void HitOrDeal(BlackjackController controller) { if (controller.Phase == RoundPhase.Betting || controller.Phase == RoundPhase.Settled) { controller.DealOrNewRound(); } else { controller.Hit(); } } internal void EditorTick() { } private static void PlaceInFrontOfPlayer(Transform root, Vector3 offset) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0049: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00cd: 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_00ea: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: 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_0092: 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) Camera main = Camera.main; Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.position : root.parent.position); Vector3 val2 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : root.parent.forward); Vector3 val3 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.right : root.parent.right); val2.y = 0f; val3.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = Vector3.forward; } ((Vector3)(ref val2)).Normalize(); ((Vector3)(ref val3)).Normalize(); Vector3 val4 = val + val3 * offset.x + val2 * offset.z; float num = FindGroundY(val4, val.y - 1.74f); root.position = new Vector3(val4.x, num + offset.y, val4.z); root.rotation = Quaternion.LookRotation(-val2, Vector3.up); Plugin.Log.LogInfo((object)("Blender GROUND aligned to world floor Y=" + num.ToString("0.###"))); } private static float FindGroundY(Vector3 requested, float fallback) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Vector3(requested.x, requested.y + 0.25f, requested.z), Vector3.down, ref val, 6f, -5, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val)).normal.y > 0.45f) { return ((RaycastHit)(ref val)).point.y; } return fallback; } private void BuildFurniture() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) try { CreateEmbeddedStaticMesh("WK_Blackjack_UpsideDownUpgradeConsole", "WhiteKnuckleBlackjack.Assets.BlackjackTableBase.obj", _assets.UpgradeConsoleMaterial, addCollision: true); CreateEmbeddedStaticMesh("WK_Blackjack_WalletDialHousing", "WhiteKnuckleBlackjack.Assets.WalletDialHousing.obj", _assets.DesktopComputerMaterial, addCollision: false); CreateEmbeddedStaticMesh("WK_Blackjack_WagerDialHousing", "WhiteKnuckleBlackjack.Assets.WagerDialHousing.obj", _assets.DesktopComputerMaterial, addCollision: false); CreateEmbeddedStaticMesh("WK_Blackjack_CardDispenser", "WhiteKnuckleBlackjack.Assets.CardDispenser.obj", _assets.RecyclerMaterial, addCollision: false); return; } catch (Exception ex) { _log.LogError((object)("Could not build the edited Blender furniture: " + ex)); } _log.LogWarning((object)"Using the emergency 2 m table fallback."); CreateBox("WK_Blackjack_EmergencyTable", _root.transform, new Vector3(0f, 1f, 0f), new Vector3(2f, 2f, 2f), _assets.FurnitureMaterial); } private void BuildDecorations() { CreateOptionalDecoration("WK_Blackjack_Radio", "WhiteKnuckleBlackjack.Assets.Radio.obj"); CreateOptionalDecoration("WK_Blackjack_Mug", "WhiteKnuckleBlackjack.Assets.Mug.obj"); CreateOptionalDecoration("WK_Blackjack_Skull", "WhiteKnuckleBlackjack.Assets.Skull.obj"); CreateOptionalDecoration("WK_Blackjack_HandWheel", "WhiteKnuckleBlackjack.Assets.HandWheel.obj"); CreateOptionalDecoration("WK_Blackjack_FrontGrate", "WhiteKnuckleBlackjack.Assets.FrontGrate.obj"); CreateOptionalDecoration("WK_Blackjack_PowerLeverHousing", "WhiteKnuckleBlackjack.Assets.PowerLeverHousing.obj"); CreateOptionalDecoration("WK_Blackjack_PowerLeverHandle", "WhiteKnuckleBlackjack.Assets.PowerLeverHandle.obj"); CreateOptionalDecoration("WK_Blackjack_Book", "WhiteKnuckleBlackjack.Assets.Book.obj"); } private void BuildInstructionNote() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0.7f, 1.785f, 0.63f); Collider component = CreateBox("WK_Blackjack_InstructionNote", _root.transform, val, new Vector3(0.6f, 0.004f, 0.34f), _assets.CardMaterial).GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } GameObject val2 = new GameObject("WK_Blackjack_InstructionNoteText"); val2.transform.SetParent(_root.transform, false); val2.transform.localPosition = val + Vector3.up * 0.003f; val2.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); TextMesh obj = val2.AddComponent<TextMesh>(); obj.text = "THIS IS BLACKJACK.\nTHE LEFT BUTTON IS \"STAND.\"\nTHE RIGHT BUTTON IS \"HIT/DEAL.\"\n\nAT THE TOP, YELLOW IS THE\nDEALER'S HAND, AND RED IS YOURS.\n\nTHE MACHINE FOLLOWS BASIC\nBLACKJACK RULES. ONCE LOST,\nYOU CANNOT GET YOUR ROACHES BACK."; obj.color = Color.black; obj.fontSize = 64; obj.characterSize = 0.00265f; obj.lineSpacing = 0.82f; obj.fontStyle = (FontStyle)1; obj.anchor = (TextAnchor)4; obj.alignment = (TextAlignment)1; obj.richText = false; } private void BuildCelebrationShooters() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) CreateOptionalDecoration("WK_Blackjack_CelebrationShooter_Left", "WhiteKnuckleBlackjack.Assets.CelebrationShooterLeft.obj"); CreateOptionalDecoration("WK_Blackjack_CelebrationShooter_Right", "WhiteKnuckleBlackjack.Assets.CelebrationShooterRight.obj"); Quaternion localRotation = Quaternion.LookRotation(new Vector3(0f, Mathf.Sin(0.61086524f), Mathf.Cos(0.61086524f)), Vector3.up); Vector3[] array = (Vector3[])(object)new Vector3[2] { new Vector3(-1.0000001f, 1.9230404f, -0.8586025f), new Vector3(0.9999999f, 1.9230404f, -0.8586025f) }; foreach (Vector3 localPosition in array) { CreateCelebrationEffect(localPosition, localRotation); } } private void CreateCelebrationEffect(Vector3 localPosition, Quaternion localRotation) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("WK_Blackjack_CelebrationEmitter"); val.transform.SetParent(_root.transform, false); val.transform.localPosition = localPosition; val.transform.localRotation = localRotation; if ((Object)(object)_assets.CelebrationParticleTemplate != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(((Component)_assets.CelebrationParticleTemplate).gameObject, val.transform, false); ((Object)val2).name = "WK_Blackjack_NativeTrainingConfetti"; val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; val2.SetActive(true); ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val3 in componentsInChildren) { MainModule main = val3.main; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)0; val3.Stop(true, (ParticleSystemStopBehavior)0); _winConfetti.Add(val3); } AudioSource[] componentsInChildren2 = val2.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val4 in componentsInChildren2) { val4.playOnAwake = false; val4.Stop(); _winSounds.Add(val4); } } else { _log.LogWarning((object)"Native training-finish confetti was not available for a blackjack shooter."); } if ((Object)(object)_assets.CelebrationWhistleTemplate != (Object)null) { AudioSource val5 = val.AddComponent<AudioSource>(); CopyAudioSource(_assets.CelebrationWhistleTemplate, val5); val5.playOnAwake = false; _winSounds.Add(val5); } else { _log.LogWarning((object)"Native tutorial-finish whistle was not available for a blackjack shooter."); } } private static void CopyAudioSource(AudioSource source, AudioSource destination) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) destination.clip = source.clip; destination.outputAudioMixerGroup = source.outputAudioMixerGroup; destination.mute = source.mute; destination.bypassEffects = source.bypassEffects; destination.bypassListenerEffects = source.bypassListenerEffects; destination.bypassReverbZones = source.bypassReverbZones; destination.priority = source.priority; destination.volume = source.volume; destination.pitch = source.pitch; destination.panStereo = source.panStereo; destination.spatialBlend = source.spatialBlend; destination.reverbZoneMix = source.reverbZoneMix; destination.dopplerLevel = source.dopplerLevel; destination.spread = source.spread; destination.rolloffMode = source.rolloffMode; destination.minDistance = source.minDistance; destination.maxDistance = source.maxDistance; destination.loop = false; } private void BuildLossEffect() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) CreateLossParticleEffect(_assets.LossSmokeTemplate, "WK_Blackjack_LossSmoke", new Vector3(0f, 2.48f, -0.57f), Quaternion.identity); if ((Object)(object)_assets.LossFailureClip != (Object)null) { GameObject val = new GameObject("WK_Blackjack_LossAudio"); val.transform.SetParent(_root.transform, false); val.transform.localPosition = new Vector3(0f, 2.24f, -0.53f); _lossSound = val.AddComponent<AudioSource>(); _lossSound.clip = _assets.LossFailureClip; AudioSource? lossSound = _lossSound; AudioSource? celebrationWhistleTemplate = _assets.CelebrationWhistleTemplate; lossSound.outputAudioMixerGroup = ((celebrationWhistleTemplate != null) ? celebrationWhistleTemplate.outputAudioMixerGroup : null); _lossSound.playOnAwake = false; _lossSound.loop = false; _lossSound.volume = 0.9f; _lossSound.spatialBlend = 1f; _lossSound.rolloffMode = (AudioRolloffMode)0; _lossSound.minDistance = 1.5f; _lossSound.maxDistance = 18f; } else { _log.LogWarning((object)"Native electrical power-down sound was not available for the loss cue."); } } private void CreateLossParticleEffect(ParticleSystem? template, string name, Vector3 localPosition, Quaternion localRotation) { //IL_0045: 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_005e: 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_0085: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template == (Object)null) { _log.LogWarning((object)(name + " could not find its native White Knuckle particle template.")); return; } GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, _root.transform, false); ((Object)val).name = name; val.transform.localPosition = localPosition; val.transform.localRotation = localRotation; val.transform.localScale = Vector3.one; val.SetActive(true); ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val2 in componentsInChildren) { MainModule main = val2.main; ((MainModule)(ref main)).playOnAwake = false; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)0; val2.Stop(true, (ParticleSystemStopBehavior)0); _lossParticles.Add(val2); } AudioSource[] componentsInChildren2 = val.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource obj in componentsInChildren2) { obj.playOnAwake = false; obj.Stop(); ((Behaviour)obj).enabled = false; } } private void PlayRoundEffects(RoundOutcome outcome) { if (outcome == RoundOutcome.DealerWin) { PlayLossEffect(); } else { PlayWinCelebration(outcome); } } private void PlayLossEffect() { foreach (ParticleSystem lossParticle in _lossParticles) { if (!((Object)(object)lossParticle == (Object)null)) { lossParticle.Stop(true, (ParticleSystemStopBehavior)0); lossParticle.Play(true); } } if ((Object)(object)_lossSound != (Object)null && (Object)(object)_lossSound.clip != (Object)null) { _lossSound.Stop(); _lossSound.Play(); } _log.LogInfo((object)"Blackjack loss: fired native machine smoke and power-down audio."); } private void PlayWinCelebration(RoundOutcome outcome) { if (outcome != RoundOutcome.PlayerWin && outcome != RoundOutcome.PlayerBlackjack) { return; } foreach (ParticleSystem item in _winConfetti) { if (!((Object)(object)item == (Object)null)) { item.Stop(true, (ParticleSystemStopBehavior)0); item.Play(true); } } foreach (AudioSource winSound in _winSounds) { if (!((Object)(object)winSound == (Object)null) && !((Object)(object)winSound.clip == (Object)null)) { winSound.Stop(); winSound.Play(); } } _log.LogInfo((object)"Blackjack win: fired both 35-degree training confetti shooters."); } private void BuildHandDisplay() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_00a2: Unknown result type (might be due to invalid IL or missing references) try { CreateEmbeddedStaticMesh("WK_Blackjack_HandDisplay", "WhiteKnuckleBlackjack.Assets.HandDisplay.obj", _assets.DesktopComputerMaterial, addCollision: false); _playerHandReadout = CreateScreenText("WK_Blackjack_PlayerHandReadout", new Vector3(-0.33862492f, 2.3457873f, -0.6752408f)); _playerTotalReadout = CreateScreenText("WK_Blackjack_PlayerTotalReadout", new Vector3(-0.07037853f, 2.3457875f, -0.6752409f)); _dealerHandReadout = CreateScreenText("WK_Blackjack_DealerHandReadout", new Vector3(0.15956767f, 2.3457873f, -0.6752408f)); _dealerTotalReadout = CreateScreenText("WK_Blackjack_DealerTotalReadout", new Vector3(0.4137063f, 2.3457873f, -0.6752409f)); } catch (Exception ex) { _log.LogWarning((object)("Could not add the Blender-authored hand display: " + ex.Message)); } } private TextMesh CreateScreenText(string name, Vector3 panelCenter) { //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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0.25881907f, 0.96592575f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, 0.9659258f, -0.25881904f); GameObject val3 = new GameObject(name); val3.transform.SetParent(_root.transform, false); val3.transform.localPosition = panelCenter + val * 0.0025f; val3.transform.localRotation = Quaternion.LookRotation(-val, val2); TextMesh obj = val3.AddComponent<TextMesh>(); obj.text = "--"; obj.color = new Color(1f, 0.92f, 0.72f, 1f); obj.fontSize = 64; obj.characterSize = 0.0075f; obj.fontStyle = (FontStyle)1; obj.anchor = (TextAnchor)4; obj.alignment = (TextAlignment)1; obj.richText = false; return obj; } private void RenderHandDisplay(BlackjackController controller) { SetScreenText(_playerHandReadout, controller.PlayerHandReadout, 0.29452705f, 0.0075f); SetScreenText(_playerTotalReadout, controller.PlayerTotalReadout, 0.14453761f, 0.012f); SetScreenText(_dealerHandReadout, controller.DealerHandReadout, 0.26623788f, 0.0075f); SetScreenText(_dealerTotalReadout, controller.DealerTotalReadout, 0.14453758f, 0.012f); } private static void SetScreenText(TextMesh? text, string value, float panelWidth, float preferredSize) { if (!((Object)(object)text == (Object)null)) { text.text = value; float num = Math.Max(1f, (float)value.Length * 0.55f * (float)text.fontSize * 0.1f); text.characterSize = Math.Min(preferredSize, panelWidth * 0.9f / num); } } private void CreateOptionalDecoration(string name, string resourceName) { try { CreateEmbeddedStaticMesh(name, resourceName, _assets.FurnitureMaterial, addCollision: false); } catch (Exception ex) { _log.LogWarning((object)("Could not add optional Blender decoration " + name + ": " + ex.Message)); } } private GameObject CreateEmbeddedStaticMesh(string name, string resourceName, Material? material, bool addCollision) { return CreateEmbeddedMesh(name, _root.transform, resourceName, material, addCollision); } private GameObject CreateEmbeddedMesh(string name, Transform parent, string resourceName, Material? material, bool addCollision) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); EmbeddedObjLoader.LoadedObj loadedObj = EmbeddedObjLoader.Load(resourceName); Mesh mesh = loadedObj.Mesh; _generatedMeshes.Add(mesh); val.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); if (loadedObj.MaterialNames.Length != 0) { Material[] array = (Material[])(object)new Material[loadedObj.MaterialNames.Length]; for (int i = 0; i < array.Length; i++) { array[i] = (resourceName.EndsWith("LayoutLabels.obj", StringComparison.Ordinal) ? (material ?? ((Renderer)val2).sharedMaterial) : (_assets.MaterialNamed(loadedObj.MaterialNames[i], material) ?? material ?? ((Renderer)val2).sharedMaterial)); } ((Renderer)val2).sharedMaterials = array; } else if ((Object)(object)material != (Object)null) { ((Renderer)val2).sharedMaterial = material; } if (addCollision) { MeshCollider obj = val.AddComponent<MeshCollider>(); obj.sharedMesh = mesh; obj.convex = false; } return val; } private CL_Button? CreateButton(string name, string visualResourceName, Vector3 colliderCenter, Vector3 colliderSize, GameObject? template, Action action) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_0107: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown CreateEmbeddedStaticMesh(name + "_ExactBlenderVisual", visualResourceName, _assets.FurnitureMaterial, addCollision: false); GameObject val = new GameObject(name + "_InvisibleInteraction"); val.SetActive(false); val.transform.SetParent(_root.transform, false); val.transform.localPosition = colliderCenter; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; if ((Object)(object)template != (Object)null) { val.layer = template.layer; } BoxCollider obj = val.AddComponent<BoxCollider>(); obj.size = colliderSize; ((Collider)obj).isTrigger = false; CL_Button val2 = val.AddComponent<CL_Button>(); val.AddComponent<ObjectTagger>().tags = new List<string> { "Button" }; val2.active = true; val2.maxPresses = 0; val2.pressCooldown = 0.12f; val2.projectilesCanPress = false; val2.hammerCanPress = false; val2.activeEvent = new UnityEvent(); val2.activeEvent.AddListener((UnityAction)delegate { action(); }); CopyNativeButtonSounds(val2, template, _assets.ActionButtonTemplate, _assets.BetUpButtonTemplate, _assets.BetDownButtonTemplate); _log.LogInfo((object)(name + " native press sound=" + (((Object)(object)val2.pressSound == (Object)null) ? "unavailable" : ((Object)val2.pressSound).name))); val.SetActive(true); return val2; } private static void CopyNativeButtonSounds(CL_Button target, params GameObject?[] templates) { foreach (GameObject val in templates) { if ((Object)(object)val == (Object)null) { continue; } CL_Button component = val.GetComponent<CL_Button>(); CL_HoldButton component2 = val.GetComponent<CL_HoldButton>(); if ((Object)(object)component != (Object)null) { if ((Object)(object)target.pressSound == (Object)null) { target.pressSound = component.pressSound; } if ((Object)(object)target.cooldownEndSound == (Object)null) { target.cooldownEndSound = component.cooldownEndSound; } } else if ((Object)(object)component2 != (Object)null) { if ((Object)(object)target.pressSound == (Object)null) { target.pressSound = component2.pressSound; } if ((Object)(object)target.cooldownEndSound == (Object)null) { target.cooldownEndSound = component2.letgoSound; } } if ((Object)(object)target.pressSound != (Object)null && (Object)(object)target.cooldownEndSound != (Object)null) { break; } } } private CounterDisplay CreateCounterDisplay(string name, string[] resources, Vector3[] pivots, Vector3 fallbackPosition) { //IL_0071: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); GameObject val = null; try { if (resources.Length != 3 || pivots.Length != 3) { throw new InvalidOperationException("A blackjack counter requires exactly three saved wheels."); } Transform[] array = (Transform[])(object)new Transform[3]; for (int i = 0; i < array.Length; i++) { GameObject val2 = CreateEmbeddedStaticMesh(name + "_Wheel_" + i, resources[i], _assets.CounterWheelMaterial, addCollision: false); list.Add(val2); UnmirrorCounterDigitFaces(val2); val2.transform.localPosition = pivots[i]; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; array[i] = val2.transform; } Transform[] array2 = array; val = new GameObject(name + "_NativeLogic"); val.SetActive(false); val.transform.SetParent(_root.transform, false); val.transform.localPosition = fallbackPosition; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; UT_RoachCounter obj = val.AddComponent<UT_RoachCounter>(); obj.counters = array2; obj.customInput = true; obj.negative = false; NativeCounterTicker nativeCounterTicker = val.AddComponent<NativeCounterTicker>(); nativeCounterTicker.Configure(array2, _assets.CounterTickerAudio); val.SetActive(true); CounterDisplay counterDisplay = new CounterDisplay(obj, nativeCounterTicker, null); counterDisplay.SetValue(0); return counterDisplay; } catch (Exception ex) { if ((Object)(object)val != (Object)null) { val.SetActive(false); } foreach (GameObject item in list) { if ((Object)(object)item != (Object)null) { item.SetActive(false); } } _log.LogError((object)("Could not load exact Blender counter wheels: " + ex)); GameObject val3 = new GameObject(name + "_FallbackDigits"); val3.transform.SetParent(_root.transform, false); val3.transform.localPosition = fallbackPosition; val3.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); TextMesh val4 = val3.AddComponent<TextMesh>(); val4.color = Color.white; val4.fontSize = 48; val4.characterSize = 0.0036f; val4.anchor = (TextAnchor)4; val4.alignment = (TextAlignment)1; val4.text = "000"; return new CounterDisplay(null, null, val4); } } private static void UnmirrorCounterDigitFaces(GameObject wheel) { MeshFilter component = wheel.GetComponent<MeshFilter>(); Mesh val = ((component != null) ? component.sharedMesh : null); if ((Object)(object)val == (Object)null) { return; } Vector2[] uv = val.uv; if (uv.Length == 0) { return; } float num = float.PositiveInfinity; float num2 = float.NegativeInfinity; for (int i = 0; i < uv.Length; i++) { if (!(uv[i].x >= 0.5f)) { num = Mathf.Min(num, uv[i].x); num2 = Mathf.Max(num2, uv[i].x); } } if (float.IsInfinity(num) || num2 - num < 0.0001f) { return; } float num3 = num + num2; for (int j = 0; j < uv.Length; j++) { if (uv[j].x < 0.5f) { uv[j].x = num3 - uv[j].x; } } val.uv = uv; } private static void SetButtonState(CL_Button? button, bool active) { if ((Object)(object)button == (Object)null) { return; } try { button.SetInteractable(active); } catch { button.active = active; } } private void RebuildCards(BlackjackController controller) { //IL_0076: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) if (!HandPrefixMatches(controller.DealerHand, _dealerCardVisuals) || !HandPrefixMatches(controller.PlayerHand, _playerCardVisuals)) { ClearCards(); } int num = 0; while (_playerCardVisuals.Count < controller.PlayerHand.Cards.Count || _dealerCardVisuals.Count < controller.DealerHand.Cards.Count) { if (_playerCardVisuals.Count < controller.PlayerHand.Cards.Count) { int count = _playerCardVisuals.Count; _playerCardVisuals.Add(CreateCardVisual(controller.PlayerHand.Cards[count], CardPosition(dealer: false, count), CardTextPosition(dealer: false, count), hidden: false, (float)num++ * 0.11f)); } if (_dealerCardVisuals.Count < controller.DealerHand.Cards.Count) { int count2 = _dealerCardVisuals.Count; bool hidden = controller.HideDealerHoleCard && count2 == 1; _dealerCardVisuals.Add(CreateCardVisual(controller.DealerHand.Cards[count2], CardPosition(dealer: true, count2), CardTextPosition(dealer: true, count2), hidden, (float)num++ * 0.11f)); } } for (int i = 0; i < _playerCardVisuals.Count; i++) { _playerCardVisuals[i].UpdateLabel(hidden: false); } for (int j = 0; j < _dealerCardVisuals.Count; j++) { _dealerCardVisuals[j].UpdateLabel(controller.HideDealerHoleCard && j == 1); } } private static bool HandPrefixMatches(Hand hand, List<CardVisual> visuals) { if (hand.Cards.Count < visuals.Count) { return false; } for (int i = 0; i < visuals.Count; i++) { Card card = hand.Cards[i]; if (visuals[i].Card.Rank != card.Rank || visuals[i].Card.Suit != card.Suit) { return false; } } return true; } private static Vector3 CardPosition(bool dealer, int index) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0118: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) if (index < 2) { if (dealer) { if (index != 0) { return new Vector3(0.14964f, 1.7546397f, -0.011034936f); } return new Vector3(-0.13036f, 1.7506398f, -0.011034936f); } if (index != 0) { return new Vector3(0.13721f, 1.7546397f, 0.57987f); } return new Vector3(-0.14279f, 1.7506398f, 0.57987f); } int num = index - 2; int num2 = num % 5; int num3 = num / 5; float num4 = num2 switch { 1 => -0.04f, 2 => 0.04f, 3 => -0.02f, 4 => 0.02f, _ => 0f, }; float num5; switch (num2) { case 1: case 2: num5 = -0.02f; break; case 3: case 4: num5 = -0.04f; break; default: num5 = 0f; break; } float num6 = num5 - (float)num3 * 0.06f; Vector3 val = (dealer ? new Vector3(0.009639994f, 1.7586396f, -0.24103494f) : new Vector3(-0.002790004f, 1.7586396f, 0.34987f)); return new Vector3(val.x + num4, val.y + (float)num * 0.004f, val.z + num6); } private static Vector3 CardTextPosition(bool dealer, int index) { //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_0025: 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_0037: 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_000e: 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) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = CardPosition(dealer, index); if (dealer && index == 0) { return new Vector3(val.x, 1.7459306f, val.z); } return new Vector3(val.x, val.y - 0.004709192f, val.z); } private CardVisual CreateCardVisual(Card value, Vector3 localPosition, Vector3 textPosition, bool hidden, float delay) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026f: 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) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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) Item val = null; float num = 1f; Renderer[] array = Array.Empty<Renderer>(); GameObject val2; Renderer[] array2; if ((Object)(object)_assets.CardTemplate != (Object)null) { val2 = Object.Instantiate<GameObject>(_assets.CardTemplate, _root.transform, false); ((Object)val2).name = "WK_Blackjack_Card"; val2.SetActive(false); Item_Object component = val2.GetComponent<Item_Object>(); if (component?.itemData != null) { val = component.itemData.GetClone((Item)null, false); val.dataModules?.RemoveAll((Item_Data module) => module is Item_Data_Text); val.SetFirstDataStringsofType("text", hidden ? "Dealer card (hidden)" : CardHeldName(value)); component.itemData = val; val.InitializeItemData(component); } array = val2.GetComponentsInChildren<Renderer>(true); array2 = array; foreach (Renderer obj in array2) { obj.enabled = false; obj.forceRenderingOff = true; } val2.transform.localScale = Vector3.one * 0.56294465f; num = 1.7763736f; } else { val2 = new GameObject("WK_Blackjack_Card"); val2.transform.SetParent(_root.transform, false); } val2.transform.localPosition = localPosition; val2.transform.localRotation = Quaternion.identity; GameObject val3 = CreateEmbeddedMesh("WK_Blackjack_Card_ExactBlenderVisual", val2.transform, "WhiteKnuckleBlackjack.Assets.CardMesh.obj", _assets.CardMaterial, addCollision: false); val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.identity; val3.transform.localScale = Vector3.one * num; if ((Object)(object)val2.GetComponentInChildren<Collider>(true) == (Object)null) { Mesh sharedMesh = val3.GetComponent<MeshFilter>().sharedMesh; BoxCollider obj2 = val2.AddComponent<BoxCollider>(); Bounds bounds = sharedMesh.bounds; obj2.center = ((Bounds)(ref bounds)).center * num; bounds = sharedMesh.bounds; obj2.size = ((Bounds)(ref bounds)).size * num; val2.AddComponent<Rigidbody>(); } val2.SetActive(true); array2 = array; foreach (Renderer val4 in array2) { if ((Object)(object)val4 != (Object)null) { val4.enabled = false; val4.forceRenderingOff = true; } } TextMesh val5 = AddCardText("", textPosition, 0.1f, Color.black); if ((Object)(object)val5 != (Object)null) { ((Component)val5).transform.SetParent(val2.transform, true); } CardVisual cardVisual = new CardVisual(value, val2, val5, val, hidden); cardVisual.UpdateLabel(hidden); val2.AddComponent<DealtCardMotion>().Configure(_root.transform, new Vector3(0.01461f, 1.9006397f, -0.5f), localPosition, delay); return cardVisual; } private static string CardHeldName(Card card) { return card.Rank switch { 1 => "Ace", 11 => "Jack", 12 => "Queen", 13 => "King", _ => card.Rank.ToString(), } + " of " + card.Suit switch { 0 => "Spades", 1 => "Hearts", 2 => "Diamonds", _ => "Clubs", }; } private TextMesh? AddCardText(string value, Vector3 localPosition, float characterSize, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_002d: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("WK_Blackjack_Text_" + value); val.transform.SetParent(_root.transform, false); val.transform.localPosition = localPosition; val.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); TextMesh obj = val.AddComponent<TextMesh>(); obj.text = value; obj.color = color; obj.fontSize = 48; obj.characterSize = characterSize * 0.08f; obj.anchor = (TextAnchor)4; obj.alignment = (TextAlignment)1; return obj; } catch (Exception ex) { _log.LogWarning((object)("Could not create blackjack label: " + ex.Message)); return null; } } private static GameObject CreateBox(string name, Transform parent, Vector3 localPosition, Vector3 localScale, Material? material) { //IL_0021: 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) GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = name; val.transform.SetParent(parent, false); val.transform.localPosition = localPosition; val.transform.localScale = localScale; if ((Object)(object)material != (Object)null) { ((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = material; } return val; } public void Dispose() { _controller.RoundSettled -= PlayRoundEffects; ClearCards(); if ((Object)(object)_root != (Object)null) { _root.SetActive(false); Object.Destroy((Object)(object)_root); } foreach (Mesh generatedMesh in _generatedMeshes) { if ((Object)(object)generatedMesh != (Object)null) { Object.Destroy((Object)(object)generatedMesh); } } _generatedMeshes.Clear(); } private void ClearCards() { foreach (CardVisual dealerCardVisual in _dealerCardVisuals) { if ((Object)(object)dealerCardVisual.GameObject != (Object)null) { Object.Destroy((Object)(object)dealerCardVisual.GameObject); } } foreach (CardVisual playerCardVisual in _playerCardVisuals) { if ((Object)(object)playerCardVisual.GameObject != (Object)null) { Object.Destroy((Object)(object)playerCardVisual.GameObject); } } _dealerCardVisuals.Clear(); _playerCardVisuals.Clear(); } } internal sealed class NativeCounterTicker : MonoBehaviour { private Transform[] _wheels = Array.Empty<Transform>(); private readonly int[] _digits = new int[3]; private UT_AudioClipHandler? _audio; private int _pendingWheelMask; private float _nextTickAt; private bool _initialized; internal void Configure(Transform[] wheels, UT_AudioClipHandler? audio) { _wheels = wheels; _audio = audio; } internal void SetValue(int value) { int num = Math.Min(999, Math.Max(0, value)); for (int i = 0; i < _digits.Length; i++) { int num2 = num % 10; if (_initialized && num2 != _digits[i]) { _pendingWheelMask |= 1 << i; } _digits[i] = num2; num /= 10; } _initialized = true; } private void Update() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) UT_AudioClipHandler audio = _audio; if ((Object)(object)audio == (Object)null || _pendingWheelMask == 0 || Time.timeScale < 0.8f || Time.unscaledTime < _nextTickAt) { return; } int num = Math.Min(_wheels.Length, _digits.Length); for (int i = 0; i < num; i++) { int num2 = 1 << i; if ((_pendingWheelMask & num2) != 0) { Transform val = _wheels[i]; _pendingWheelMask &= ~num2; _nextTickAt = Time.unscaledTime + 0.075f; if ((Object)(object)val == (Object)null) { return; } try { audio.PlaySound("vending:ticker", val.position); return; } catch { _audio = null; return; } } } _pendingWheelMask = 0; } } internal sealed class DealtCardMotion : MonoBehaviour { private Transform? _table; private Vector3 _start; private Vector3 _target; private Quaternion _startRotation; private Quaternion _targetRotation; private Rigidbody[] _bodies = Array.Empty<Rigidbody>(); private Collider[] _colliders = Array.Empty<Collider>(); private bool[] _bodyWasKinematic = Array.Empty<bool>(); private bool[] _bodyUsedGravity = Array.Empty<bool>(); private bool[] _colliderWasEnabled = Array.Empty<bool>(); private float _delay; private float _elapsed; private bool _finished; internal void Configure(Transform table, Vector3 start, Vector3 target, float delay) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_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_00a8: 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) _table = table; _start = start; _target = target; _delay = delay; _startRotation = Quaternion.Euler(-28f, 0f, 0f); _targetRotation = Quaternion.identity; _bodies = ((Component)this).GetComponentsInChildren<Rigidbody>(true); _colliders = ((Component)this).GetComponentsInChildren<Collider>(true); _bodyWasKinematic = new bool[_bodies.Length]; _bodyUsedGravity = new bool[_bodies.Length]; _colliderWasEnabled = new bool[_colliders.Length]; ((Component)this).transform.SetParent(table, false); ((Component)this).transform.localPosition = start; ((Component)this).transform.localRotation = _startRotation; for (int i = 0; i < _bodies.Length; i++) { Rigidbody val = _bodies[i]; _bodyWasKinematic[i] = val.isKinematic; _bodyUsedGravity[i] = val.useGravity; val.useGravity = false; val.isKinematic = true; } for (int j = 0; j < _colliders.Length; j++) { _colliderWasEnabled[j] = _colliders[j].enabled; _colliders[j].enabled = false; } } private void Update() { //IL_006a: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) if (_finished || (Object)(object)_table == (Object)null) { return; } _elapsed += Time.unscaledDeltaTime; if (_elapsed < _delay) { return; } float num = Mathf.Clamp01((_elapsed - _delay) / 0.52f); float num2 = num * num * (3f - 2f * num); ((Component)this).transform.localPosition = Vector3.Lerp(_start, _target, num2) + Vector3.up * (Mathf.Sin(num * MathF.PI) * 0.28f); ((Component)this).transform.localRotation = Quaternion.Slerp(_startRotation, _targetRotation, num2); if (num < 1f) { return; } _finished = true; ((Component)this).transform.localPosition = _target; ((Component)this).transform.localRotation = _targetRotation; for (int i = 0; i < _colliders.Length; i++) { if ((Object)(object)_colliders[i] != (Object)null) { _colliders[i].enabled = _colliderWasEnabled[i]; } } for (int j = 0; j < _bodies.Length; j++) { Rigidbody val = _bodies[j]; if (!((Object)(object)val == (Object)null)) { val.isKinematic = _bodyWasKinematic[j]; val.useGravity = _bodyUsedGravity[j]; if (!val.isKinematic) { val.velocity = _table.TransformDirection(new Vector3(0f, -0.03f, 0.04f)); } } } Object.Destroy((Object)(object)this); } } [BepInPlugin("com.battery_boy.whiteknuckle.blackjack", "Safehouse Blackjack", "0.5.1")] public sealed class Plugin : BaseUnityPlugin { private readonly struct InterludePlacement { internal readonly string LevelToken; internal readonly bool HasAuthoredLocalTransform; internal readonly Vector3 LocalPosition; internal readonly Quaternion LocalRotation; internal InterludePlacement(string levelToken) { //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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) LevelToken = levelToken; HasAuthoredLocalTransform = false; LocalPosition = Vector3.zero; LocalRotation = Quaternion.identity; } internal InterludePlacement(string levelToken, Vector3 localPosition, Quaternion localRotation) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) LevelToken = levelToken; HasAuthoredLocalTransform = true; LocalPosition = localPosition; LocalRotation = localRotation; } } public const string PluginGuid = "com.battery_boy.whiteknuckle.blackjack"; public const string PluginName = "Safehouse Blackjack"; public const string PluginVersion = "0.5.1"; internal static ManualLogSource Log = null; internal static ModConfig Settings = null; internal static Plugin Instance = null; private BlackjackController? _controller; private PhysicalTable? _table; private BlackjackRuntimeDriver? _driver; private BlackjackAnnouncementPlayer? _announcements; private Harmony? _harmony; private M_Level? _firstRoom; private Transform? _activeInterludeRoot; private InterludePlacement? _activeInterludePlacement; private float _interludePlacementReadyAt; private GameObject? _runtimeAnchor; private float _nextSafeCheck; private float _showHintUntil; private bool _wasSafe; private bool _updateObserved; private int _lastRuntimeFrame = -1; private static readonly InterludePlacement[] FirstInterludePlacements = new InterludePlacement[3] { new InterludePlacement("Campaign_Interlude_Silo_To_Pipeworks_01", new Vector3(-0.10492229f, 48.652714f, 11.552661f), new Quaternion(0f, -1f, 0f, 0f)), new InterludePlacement("M5_Habitation_Shaft_Inter01"), new InterludePlacement("Campaign_Interlude_Habitation_To_Abyss_01") }; private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Settings = new ModConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.battery_boy.whiteknuckle.blackjack"); InstallRuntimePatches(); SceneManager.sceneLoaded += OnSceneLoaded; GameObject val = new GameObject("WK_Blackjack_RuntimeDriver"); Object.DontDestroyOnLoad((Object)(object)val); _driver = val.AddComponent<BlackjackRuntimeDriver>(); _announcements = val.AddComponent<BlackjackAnnouncementPlayer>(); _announcements.Configure(Settings.PAAnnouncementChancePercent.Value, Log); CreateController(); Log.LogInfo((object)"Safehouse Blackjack 0.5.1 loaded"); } private void InstallRuntimePatches() { InstallPostfix(typeof(M_Level), "Awake", "LevelAwakePostfix"); InstallPostfix(typeof(M_Level), "OnEnter", "LevelEnterPostfix"); InstallPostfix(typeof(ENT_Player), "Start", "PlayerStartPostfix"); InstallPostfix(typeof(ENT_Player), "Update", "PlayerUpdatePostfix"); } private void InstallPostfix(Type targetType, string targetName, string patchName) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown try { MethodInfo methodInfo = AccessTools.Method(targetType, targetName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(BlackjackRuntimePatches), patchName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Log.LogError((object)("Blackjack hook missing: " + targetType.Name + "." + targetName)); return; } _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); bool flag = patchInfo != null && patchInfo.Owners.Contains("com.battery_boy.whiteknuckle.blackjack"); Log.LogInfo((object)("Blackjack hook " + targetType.Name + "." + targetName + " installed=" + flag)); } catch (Exception ex) { Log.LogError((object)("Blackjack hook failed for " + targetType.Name + "." + targetName + ": " + ex)); } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; Log.LogWarning((object)"Blackjack Unity plugin host was destroyed; persistent static runtime remains available."); } private void CreateController() { _controller?.Dispose(); _controller = new BlackjackController(Settings, Log); _controller.Changed += RefreshTable; if ((Object)(object)_announcements != (Object)null) { _controller.RoundSettled += _announcements.QueueAfterRound; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { _wasSafe = false; _nextSafeCheck = 0f; _showHintUntil = Time.unscaledTime + 15f; if (TryGetActiveExactPlacement(out Transform root, out InterludePlacement _)) { if (_table != null && _table.IsAlive && !_table.IsAuthoredRoomLocalFor(root)) { DestroyTable(); } DestroyRuntimeAnchor(); _interludePlacementReadyAt = 0f; Log.LogInfo((object)"Scene loaded while exact authored interlude remains active; preserving its room-local placement state."); } else { _activeInterludeRoot = null; _activeInterludePlacement = null; DestroyTable(); DestroyRuntimeAnchor(); } } internal unsafe void RuntimeUpdate() { //IL_0116: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) if (_lastRuntimeFrame == Time.frameCount) { return; } _lastRuntimeFrame = Time.frameCount; if (!_updateObserved) { _updateObserved = true; Log.LogInfo((object)"Blackjack runtime update loop started."); } _controller?.Tick(); _table?.EditorTick(); HandleFallbackKeys(); if (!Settings.Enabled.Value || Time.unscaledTime < _nextSafeCheck) { return; } _nextSafeCheck = Time.unscaledTime + 0.4f; Transform val = FindCurrentSafeAreaRoot(); bool flag = IsSafeNow() || (Object)(object)val != (Object)null; bool flag2 = _table == null || !_table.IsAlive; InterludePlacement? activeInterludePlacement = _activeInterludePlacement; bool flag3 = (Object)(object)_activeInterludeRoot != (Object)null && activeInterludePlacement.HasValue; if (flag2 && flag3 && Time.unscaledTime >= _interludePlacementReadyAt) { InterludePlacement value = activeInterludePlacement.Value; Vector3 position; Quaternion rotation; string anchorName; if (value.HasAuthoredLocalTransform) { SpawnTableAtLocal(_activeInterludeRoot, value.LocalPosition, value.LocalRotation, value.LevelToken + " exact Blender room-local placement"); } else if (TryCalculateRoomPlacement(_activeInterludeRoot, out position, out rotation, out anchorName)) { SpawnTableAt(_activeInterludeRoot, position, rotation, value.LevelToken + " room-local automatic placement"); ManualLogSource log = Log; string[] obj = new string[5] { "Automatically placed interlude machine from room anchor ", anchorName, " at ", null, null }; Vector3 val2 = position; obj[3] = ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString(); obj[4] = "."; log.LogInfo((object)string.Concat(obj)); } } if (flag && flag2 && !flag3) { string reason = (((Object)(object)val != (Object)null) ? "safe-area bounds" : "game safe flag"); SpawnTable(val, reason); } else if (!flag && _wasSafe && !flag3) { DestroyTable(); } if (flag != _wasSafe) { Log.LogInfo((object)(flag ? "Safe area detected; placing blackjack table." : "Left safe area; removing blackjack table.")); } _wasSafe = flag; } private static bool IsSafeNow() { try { return CL_GameManager.IsSafe(); } catch { return false; } } private static Transform? FindCurrentSafeAreaRoot() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //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_0074: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { return null; } Vector3 position = ((Component)playerObject).transform.position; M_Level[] array = Object.FindObjectsOfType<M_Level>(); foreach (M_Level val in array) { if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy || !val.safeArea) { continue; } try { Bounds val2 = val.CalculateBounds(); ((Bounds)(ref val2)).Expand(2f); Vector3 val3 = ((Component)val).transform.InverseTransformPoint(position); if (((Bounds)(ref val2)).Contains(val3)) { return ((Component)val).transform; } } catch { } } return null; } private void SpawnTable(Transform? preferredRoot = null, string reason = "manual placement") { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown DestroyTable(); if (_controller == null) { return; } Transform val = preferredRoot; try { if (val == null) { val = WorldLoader.GetCurrentLevelParentRoot(); } } catch { } if ((Object)(object)val == (Object)null) { if (_runtimeAnchor == null) { _runtimeAnchor = new GameObject("WK_Blackjack_RuntimeAnchor"); } val = _runtimeAnchor.transform; Log.LogWarning((object)"No current level root was available; using a temporary scene anchor."); } try { _table = PhysicalTable.Create(val, _controller, Settings, Log); RefreshTable(); Log.LogInfo((object)("Blackjack table placed (" + reason + ").")); } catch (Exception ex) { _table = null; Log.LogError((object)("Blackjack table placement failed: " + ex)); } } private void DestroyTable() { _table?.Dispose(); _table = null; } private void DestroyRuntimeAnchor() { if ((Object)(object)_runtimeAnchor != (Object)null) { Object.Destroy((Object)(object)_runtimeAnchor); } _runtimeAnchor = null; } private void RefreshTable() { _table?.Render(_controller); } private void HandleFallbackKeys() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) if (_controller == null || !Settings.KeyboardFallback.Value) { return; } if (Input.GetKeyDown(Settings.RespawnTableKey.Value)) { Log.LogInfo((object)"F6 manual table placement requested."); _showHintUntil = Time.unscaledTime + 15f; SpawnTable(null, "F6 manual placement"); return; } PhysicalTable? table = _table; if ((table == null || !table.IsEditing) && (_table != null || _wasSafe)) { if (Input.GetKeyDown(Settings.IncreaseBetKey.Value)) { _controller.IncreaseBet(); } if (Input.GetKeyDown(Settings.DecreaseBetKey.Value)) { _controller.DecreaseBet(); } if (Input.GetKeyDown(Settings.DealKey.Value)) { _controller.DealOrNewRound(); } if (Input.GetKeyDown(Settings.HitKey.Value)) { _controller.Hit(); } if (Input.GetKeyDown(Settings.StandKey.Value)) { _controller.Stand(); } if (Input.GetKeyDown(Settings.DoubleKey.Value)) { _controller.DoubleDown(); } } } internal void DrawGui() { } internal void LevelEntered(M_Level level) { //IL_0127: 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) if ((Object)(object)level == (Object)null || !Settings.Enabled.Value) { return; } string text = AssetCatalog.HierarchyPath(((Component)level).transform); bool flag = text.IndexOf("Interlude", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)level).name.IndexOf("Interlude", StringComparison.OrdinalIgnoreCase) >= 0; Log.LogInfo((object)("Entered level: " + text + " (interlude=" + flag + ")")); if (!flag) { return; } if (TryGetInterludePlacement(((Component)level).transform, out var result)) { bool flag2 = (Object)(object)_activeInterludeRoot == (Object)(object)((Component)level).transform && _activeInterludePlacement.HasValue; _activeInterludeRoot = ((Component)level).transform; _activeInterludePlacement = result; if (result.HasAuthoredLocalTransform) { _interludePlacementReadyAt = 0f; if (!flag2 || _table == null || !_table.IsAlive || !_table.IsAuthoredRoomLocalFor(((Component)level).transform)) { SpawnTableAtLocal(((Component)level).transform, result.LocalPosition, result.LocalRotation, result.LevelToken + " exact Blender placement on interlude entry"); } return; } if (!flag2) { DestroyTable(); } _interludePlacementReadyAt = Time.unscaledTime + 3f; Log.LogInfo((object)"Configured interlude detected; waiting for its room-local anchor to settle."); } else { _activeInterludeRoot = ((Component)level).transform; _activeInterludePlacement = null; DestroyTable(); SpawnTable(((Component)level).transform, "interlude entry"); } } internal void LocalPlayerStarted(ENT_Player player) { //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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_010d: 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) //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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)ENT_Player.playerObject || !Settings.Enabled.Value) { return; } if (TryGetActiveExactPlacement(out Transform root, out InterludePlacement placement)) { if (_table == null || !_table.IsAlive || !_table.IsAuthoredRoomLocalFor(root)) { SpawnTableAtLocal(root, placement.LocalPosition, placement.LocalRotation, placement.LevelToken + " exact placement protected from player Start"); } Log.LogInfo((object)"Skipped first-room player-relative table because an exact authored interlude is active."); return; } ManualLogSource log = Log; Scene activeScene = SceneManager.GetActiveScene(); log.LogInfo((object)("Local player started in " + ((Scene)(ref activeScene)).name + "; placing first-room blackjack table.")); if ((Object)(object)_firstRoom != (Object)null && (Object)(object)_firstRoom.spawnPosition != (Object)null) { Transform spawnPosition = _firstRoom.spawnPosition; Vector3 forward = spawnPosition.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.01f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); Vector3 position = spawnPosition.position + forward * 1.8f; SpawnTableAt(((Component)_firstRoom).transform, position, Quaternion.LookRotation(-forward, Vector3.up), "M1_Intro_01 spawn point"); } else { SpawnTable(null, "initial player spawn"); } } internal void LevelAwake(M_Level level) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)level == (Object)null) { return; } string text = ((Object)level).name + " / " + level.levelName; if (Settings.Enabled.Value && TryGetInterludePlacement(((Component)level).transform, out var result) && result.HasAuthoredLocalTransform) { bool num = _table != null && _table.IsAlive && _table.IsAuthoredRoomLocalFor(((Component)level).transform); _activeInterludeRoot = ((Component)level).transform; _activeInterludePlacement = result; _interludePlacementReadyAt = 0f; if (!num) { SpawnTableAtLocal(((Component)level).transform, result.LocalPosition, result.LocalRotation, result.LevelToken + " exact Blender placement during M_Level.Awake"); } } if (text.IndexOf("M1_Intro_01", StringComparison.OrdinalIgnoreCase) >= 0) { _firstRoom = level; Log.LogInfo((object)("Found first playable room: " + text + "; spawn marker=" + (((Object)(object)level.spawnPosition == (Object)null) ? "missing" : ((object)level.spawnPosition.position/*cast due to .constrained prefix*/).ToString()))); } } private unsafe void SpawnTableAt(Transform levelRoot, Vector3 position, Quaternion rotation, string reason) { //IL_0012: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) DestroyTable(); if (_controller == null) { return; } try { _table = PhysicalTable.CreateAt(levelRoot, position, rotation, _controller, Settings, Log); RefreshTable(); ManualLogSource log = Log; string[] obj = new string[5] { "Blackjack table placed at ", null, null, null, null }; Vector3 val = position; obj[1] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString(); obj[2] = " ("; obj[3] = reason; obj[4] = ")."; log.LogInfo((object)string.Concat(obj)); } catch (Exception ex) { _table = null; Log.LogError((object)("Blackjack fixed placement failed: " + ex)); } } private unsafe void SpawnTableAtLocal(Transform levelRoot, Vector3 localPosition, Quaternion localRotation, string reason) { //IL_0018: 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) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) DestroyTable(); if (_controller == null) { return; } try { RemovePartialTableChildren(levelRoot); _table = PhysicalTable.CreateAtLocal(levelRoot, localPosition, localRotation, _controller, Settings, Log); RefreshTable(); ManualLogSource log = Log; string[] obj = new string[5] { "Blackjack table attached at room-local position ", null, null, null, null }; Vector3 val = localPosition; obj[1] = ((object)(*(Vector3*)(&val))/*cast due to .constrained