using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Autodesk.Fbx")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")]
[assembly: IgnoresAccessChecksTo("Klattersynth")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")]
[assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")]
[assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: AssemblyCompany("DirtyGames")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("REPOGambling")]
[assembly: AssemblyTitle("REPOGambling")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace REPOGambling
{
[BepInPlugin("DirtyGames.REPOGambling", "REPOGambling", "1.5.9")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class REPOGambling : BaseUnityPlugin
{
public AssetBundle bundle = null;
public bool HasLoadedABundle = false;
public string error = "";
public GameObject slotMachinePrefab;
public GameObject wheelMachinePrefab;
public GameObject[] roomModulePrefab;
public AudioClip spinSound;
public AudioClip spinSong;
public AudioClip wheelSong;
public AudioClip winSound;
public AudioClip lossSound;
public AudioClip songSound;
public AudioClip clickSound;
public AudioClip deathSound;
public AudioClip jackpotSound;
public AudioClip cheaterSound;
public int slotBet = 2;
public List<PrizeEntry> prizeEntries = new List<PrizeEntry>();
public List<string> deathLines = new List<string>();
private ConfigEntry<string> userDeathLinesEntry;
public ConfigEntry<int> wheelSpinCost;
public ConfigEntry<int> maxSlotCost;
public ConfigEntry<int> slotRewardTwoMatchMultiplier;
public ConfigEntry<int> slotRewardCloveMatchMultiplier;
public ConfigEntry<int> slotRewardBerryMatchMultiplier;
public ConfigEntry<int> slotRewardSpadeMatchMultiplier;
public ConfigEntry<int> slotRewardCherryMatchMultiplier;
public ConfigEntry<int> slotRewardAny7Multiplier;
public ConfigEntry<int> slotRewardJackpotMultiplier;
public ConfigEntry<float> roomSpawnChance;
public ConfigEntry<float> slotForceWinChance;
public Transform cachedWheelRotator;
public ConfigEntry<float> slotForceLossChance;
public ConfigEntry<SlotForceWinType> slotForceWinType;
public ConfigEntry<string> devForcePrize;
internal static REPOGambling Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
private ConfigFile Config => ((BaseUnityPlugin)this).Config;
private void Awake()
{
Instance = this;
SetupConfig();
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
Patch();
string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
foreach (string text in manifestResourceNames)
{
Logger.LogInfo((object)("Embedded resource: " + text));
}
LoadBundle("REPOGambling.gamblingbundle");
foreach (GameObject item in LoadModulePrefabsFromBundle())
{
Logger.LogInfo((object)("Registering " + ((Object)item).name));
NetworkPrefabs.RegisterNetworkPrefab("Level/Shop/Modules/" + ((Object)item).name, item);
}
roomModulePrefab = (GameObject[])(object)new GameObject[3];
roomModulePrefab[0] = this.Load<GameObject>("Module - Shop - DE - Gambling Room.prefab");
roomModulePrefab[1] = this.Load<GameObject>("Module - Shop - DE - Solo Slot.prefab");
roomModulePrefab[2] = this.Load<GameObject>("Module - Shop - DE - Solo Wheel.prefab");
lossSound = this.Load<AudioClip>("Loss.wav");
winSound = this.Load<AudioClip>("Win.wav");
spinSound = this.Load<AudioClip>("Spin.wav");
spinSong = this.Load<AudioClip>("Machine Song Loop.wav");
clickSound = this.Load<AudioClip>("Wheel Click.wav");
wheelSong = this.Load<AudioClip>("Wheel Song.wav");
deathSound = this.Load<AudioClip>("Death Error.wav");
jackpotSound = this.Load<AudioClip>("Jackpot Reward.wav");
cheaterSound = this.Load<AudioClip>("Cheater Sound.wav");
slotMachinePrefab = this.Load<GameObject>("Assets/My Mods/slot-machine/slot Machine.prefab");
if ((Object)(object)slotMachinePrefab != (Object)null)
{
NetworkPrefabs.RegisterNetworkPrefab(slotMachinePrefab);
}
else
{
Logger.LogError((object)"[REPOGambling] Failed to load 'slot machine.prefab'!");
}
wheelMachinePrefab = this.Load<GameObject>("Assets/My Mods/Wheel Machine.prefab");
if ((Object)(object)wheelMachinePrefab != (Object)null)
{
NetworkPrefabs.RegisterNetworkPrefab(wheelMachinePrefab);
}
else
{
Logger.LogWarning((object)"[REPOGambling] Wheel prefab not found or not used — skipping.");
}
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
}
public List<GameObject> LoadModulePrefabsFromBundle()
{
List<GameObject> list = new List<GameObject>();
string[] allAssetNames = bundle.GetAllAssetNames();
foreach (string text in allAssetNames)
{
if (text.ToLower().Contains("module - shop - de"))
{
GameObject val = this.Load<GameObject>(text);
if ((Object)(object)val != (Object)null)
{
list.Add(val);
Logger.LogInfo((object)("[REPOGambling] Loaded module prefab: " + text));
}
}
}
return list;
}
private void SetupConfig()
{
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Expected O, but got Unknown
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Expected O, but got Unknown
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01c9: Expected O, but got Unknown
//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Expected O, but got Unknown
//IL_0225: Unknown result type (might be due to invalid IL or missing references)
//IL_022f: Expected O, but got Unknown
//IL_0258: Unknown result type (might be due to invalid IL or missing references)
//IL_0262: Expected O, but got Unknown
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Expected O, but got Unknown
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d3: Expected O, but got Unknown
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
//IL_0311: Expected O, but got Unknown
//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
//IL_03e1: Expected O, but got Unknown
AddPrizeEntry("Upgrade1", "Upgrade", 0f, 0.05f);
AddPrizeEntry("Mystery1", "Mystery Prize", 35f, 0.12f);
AddPrizeEntry("Jackpot1", "Jackpot", 70f, 0.05f);
AddPrizeEntry("Lose1", "Lose", 105f, 0.2f);
AddPrizeEntry("Bankruptcy", "Bankruptcy", 140f, 0.05f);
AddPrizeEntry("Upgrade2", "Upgrade", 180f, 0.05f);
AddPrizeEntry("Mystery2", "Mystery Prize", 215f, 0.12f);
AddPrizeEntry("Jackpot2", "Jackpot", 250f, 0.05f);
AddPrizeEntry("Lose2", "Lose", 285f, 0.2f);
AddPrizeEntry("Death", "Death", 320f, 0.11f);
userDeathLinesEntry = Config.Bind<string>("Customization", "CustomDeathLines", "", "Comma-separated list of additional death lines players can add (e.g., 'Noooo!, Goodbye cruel world!, This sucks!')");
wheelSpinCost = Config.Bind<int>("Customization", "CustomWheelPrice", 1, new ConfigDescription("Price of the wheel per spin.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
maxSlotCost = Config.Bind<int>("Customization", "CustomMaxSlotBet", 10, new ConfigDescription("Max bet that can be placed on any slot machine.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 50), Array.Empty<object>()));
slotRewardCherryMatchMultiplier = Config.Bind<int>("SlotPayouts", "CherryMatchMultiplier", 2, new ConfigDescription("Reward multiplier for getting three matching cherry (three cherry, x bet amount)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
slotRewardBerryMatchMultiplier = Config.Bind<int>("SlotPayouts", "BerryMatchMultiplier", 2, new ConfigDescription("Reward multiplier for getting three matching berry (three berry, x bet amount)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
slotRewardSpadeMatchMultiplier = Config.Bind<int>("SlotPayouts", "SpadeMatchMultiplier", 2, new ConfigDescription("Reward multiplier for getting three matching spade (three spade, x bet amount)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
slotRewardCloveMatchMultiplier = Config.Bind<int>("SlotPayouts", "CloveMatchMultiplier", 2, new ConfigDescription("Reward multiplier for getting three matching cloves (three cloves, x bet amount)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
slotRewardJackpotMultiplier = Config.Bind<int>("SlotPayouts", "JackpotMultiplier", 7, new ConfigDescription("Reward multiplier for hitting the jackpot (three 7s, x bet amount)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
slotForceWinChance = Config.Bind<float>("Customization", "ForceSlotWinChance", 0.1f, new ConfigDescription("Chance the slot machine will force a win.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
slotForceLossChance = Config.Bind<float>("Customization", "ForceSlotLossChance", 0.15f, new ConfigDescription("Chance the slot machine will force a guaranteed loss.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
slotForceWinType = Config.Bind<SlotForceWinType>("Customization", "ForceSlotWinType", SlotForceWinType.Any, "Controls which type of win is forced when ForceSlotWinChance succeeds.");
devForcePrize = Config.Bind<string>("Developer", "ForcePrize", "", "If set to a valid prize name (e.g., 'Jackpot', 'Death'), this will override random prize selection for debugging. Leave empty to disable.");
if (slotForceWinChance.Value >= 1f)
{
Logger.LogWarning((object)"[REPOGambling] ForceSlotWinChance was set to 100%. Reverting to default (0.07).");
Logger.LogWarning((object)"[REPOGambling] Please restart your game for correct probability configuration!");
slotForceWinChance.Value = 0.07f;
}
roomSpawnChance = Config.Bind<float>("Customization", "RoomSpawnChance", 1f, new ConfigDescription("Chance the gambling room will spawn in the Shop. Ex 1.0f = 100%", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
BuildDeathLines();
}
private void BuildDeathLines()
{
deathLines = new List<string>
{
"Welp, that's my exit", "Was nice knowing ya!", "I regret everything!", "I regret nothing!", "Death... again?", "Mom I failed..", "AAAAAAAAH", "Alexa, play Despacito!", "I feel funny..", "I spun... and I lost..",
"All I got was this lousy death..", "DirtyBong was here", "Should've stayed in the truck", "Fuck you", "in a moment, it could all go", "is this tax deductible?", "WAIT.. LET ME TELL YOU SOMETHING!", "I should’ve bet on red", "I shouldn't have ate that", "Cole is gay",
"Shoutout hats", "I’m done gambling"
};
if (!string.IsNullOrWhiteSpace(userDeathLinesEntry.Value))
{
IEnumerable<string> collection = from s in userDeathLinesEntry.Value.Split(',')
select s.Trim() into s
where !string.IsNullOrEmpty(s)
select s;
deathLines.AddRange(collection);
}
}
private void AddPrizeEntry(string id, string name, float angle, float defaultWeight)
{
ConfigEntry<float> val = Config.Bind<float>("WheelPrizes", id ?? "", defaultWeight, "Chance weight for prize '" + name + "' (higher = more likely)");
prizeEntries.Add(new PrizeEntry(name, angle, val.Value));
}
internal void Patch()
{
//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)
//IL_0021: Expected O, but got Unknown
//IL_0026: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
public bool LoadBundle(string resource)
{
if (HasLoadedABundle)
{
return true;
}
try
{
if (string.IsNullOrEmpty(resource))
{
error = "Null Or Empty Resource String!";
return false;
}
Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
if (manifestResourceStream == null)
{
error = "Could not find resource stream: " + resource;
return false;
}
using MemoryStream memoryStream = new MemoryStream((int)manifestResourceStream.Length);
manifestResourceStream.CopyTo(memoryStream);
if (memoryStream.Length <= 0)
{
error = "Empty memory stream!";
return false;
}
return LoadBundle(memoryStream.ToArray());
}
catch (Exception ex)
{
error = ex.ToString();
return false;
}
}
public bool LoadBundle(byte[] resource)
{
//IL_0027: 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)
if (HasLoadedABundle)
{
return true;
}
try
{
AssetBundle val = AssetBundle.LoadFromMemory(resource);
if ((Object)(object)val != (Object)null)
{
((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
bundle = val;
HasLoadedABundle = true;
return true;
}
HasLoadedABundle = true;
}
catch (Exception ex)
{
error = ex.ToString();
return false;
}
return false;
}
public T Load<T>(string str) where T : Object
{
//IL_003d: 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)
try
{
if (HasLoadedABundle)
{
Object obj = bundle.LoadAsset(str, typeof(T));
T val = (T)(object)((obj is T) ? obj : null);
((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20);
return val;
}
}
catch (Exception ex)
{
error = ex.ToString();
}
return default(T);
}
public AudioClip GetClip(GamblingSound sound)
{
if (1 == 0)
{
}
AudioClip result = (AudioClip)(sound switch
{
GamblingSound.Spin => spinSound,
GamblingSound.SpinLoop => spinSong,
GamblingSound.WheelLoop => wheelSong,
GamblingSound.Win => winSound,
GamblingSound.Loss => lossSound,
GamblingSound.Jackpot => jackpotSound,
GamblingSound.Click => clickSound,
GamblingSound.Death => deathSound,
GamblingSound.Cheater => cheaterSound,
_ => null,
});
if (1 == 0)
{
}
return result;
}
}
[HarmonyPatch(typeof(EnvironmentDirector), "Setup")]
public class EnvironmentPlacementPatch
{
private static PlayerAvatar? playerAvatar;
private static AudioSource? wheelAudio;
private static int spinTimes;
private const float spinCooldown = 1.5f;
[HarmonyPostfix]
private static void SlotMachinePlacement()
{
if (!((Object)(object)LevelGenerator.Instance.Level == (Object)null) && !(LevelGenerator.Instance.Level.NarrativeName != "Service Station"))
{
if (REPOGambling.Instance.wheelSpinCost.Value <= 0)
{
REPOGambling.Instance.wheelSpinCost.Value = 1;
Debug.LogWarning((object)"[REPOGambling] wheelSpinCost was set to 0 or negative. Resetting to 1.");
}
SetupSlotMachines();
SetupWheelMachines();
}
}
private static void SetupSlotMachines()
{
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Expected O, but got Unknown
//IL_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_0225: Expected O, but got Unknown
//IL_026d: Unknown result type (might be due to invalid IL or missing references)
//IL_0277: Expected O, but got Unknown
IEnumerable<GameObject> enumerable = from obj in Object.FindObjectsOfType<GameObject>()
where ((Object)obj).name.Contains("Slot Machine")
select obj;
int num = 0;
foreach (GameObject slot in enumerable)
{
num++;
Transform val = slot.transform.Find("GFX/pachinko/Handle");
Transform val2 = slot.transform.Find("Bet Up");
Transform val3 = slot.transform.Find("Bet Down");
Transform obj2 = slot.transform.Find("Bet Text");
TextMeshPro val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshPro>() : null);
if ((Object)(object)val4 != (Object)null)
{
((TMP_Text)val4).text = $"Bet: ${REPOGambling.Instance.slotBet}K";
}
if ((Object)(object)slot.GetComponent<SlotMachineState>() == (Object)null)
{
slot.AddComponent<SlotMachineState>();
}
if ((Object)(object)slot.GetComponent<GamblingAudioRPCHandler>() == (Object)null)
{
slot.AddComponent<GamblingAudioRPCHandler>();
}
EnsurePhotonComponents(slot);
PhysGrabObjectGrabArea grabArea = ((val != null) ? ((Component)val).GetComponent<PhysGrabObjectGrabArea>() : null);
if (grabArea != null)
{
grabArea.grabAreas[0].grabAreaEventOnStart.AddListener((UnityAction)delegate
{
SpinSlotMachine(slot, grabArea.GetLatestGrabber());
});
}
else
{
Debug.LogWarning((object)"[REPOGambling] Slot machine handle not found!");
}
PhysGrabObjectGrabArea val5 = ((val2 != null) ? ((Component)val2).GetComponent<PhysGrabObjectGrabArea>() : null);
if (val5 != null)
{
val5.grabAreas[0].grabAreaEventOnStart.AddListener((UnityAction)delegate
{
UpdateMachineBet(slot, increase: true);
});
}
else
{
Debug.Log((object)"[REPOGambling] Raise Bet button missing!");
}
PhysGrabObjectGrabArea val6 = ((val3 != null) ? ((Component)val3).GetComponent<PhysGrabObjectGrabArea>() : null);
if (val6 != null)
{
val6.grabAreas[0].grabAreaEventOnStart.AddListener((UnityAction)delegate
{
UpdateMachineBet(slot, increase: false);
});
}
else
{
Debug.Log((object)"[REPOGambling] Lower Bet button missing!");
}
Debug.Log((object)"[REPOGambling] Setup Slot machine!");
}
if (num == 0)
{
Debug.Log((object)"[REPOGambling] No Slot Machines found in this level.");
}
}
private static void SetupWheelMachines()
{
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Expected O, but got Unknown
IEnumerable<GameObject> enumerable = from obj in Object.FindObjectsOfType<GameObject>()
where ((Object)obj).name.Contains("Wheel Machine")
select obj;
int num = 0;
foreach (GameObject wheel in enumerable)
{
num++;
if ((Object)(object)wheel.GetComponent<WheelMachineState>() == (Object)null)
{
wheel.AddComponent<WheelMachineState>();
}
if ((Object)(object)wheel.GetComponent<GamblingAudioRPCHandler>() == (Object)null)
{
wheel.AddComponent<GamblingAudioRPCHandler>();
}
Transform val = wheel.transform.Find("Handle");
PhysGrabObjectGrabArea grabArea = ((val != null) ? ((Component)val).GetComponent<PhysGrabObjectGrabArea>() : null);
if (grabArea != null)
{
grabArea.grabAreas[0].grabAreaEventOnStart.AddListener((UnityAction)delegate
{
SpinWheel(wheel, grabArea.GetLatestGrabber());
});
Debug.Log((object)"[REPOGambling] Setup Wheel!");
}
else
{
Debug.LogWarning((object)"[REPOGambling] Wheel button not found or missing grab area.");
}
EnsurePhotonComponents(wheel);
}
if (num == 0)
{
Debug.Log((object)"[REPOGambling] No Wheel Machines found in this level.");
}
}
private static void EnsurePhotonComponents(GameObject obj)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
PhotonView val = obj.GetComponent<PhotonView>();
if ((Object)(object)val == (Object)null)
{
val = obj.AddComponent<PhotonView>();
}
val.ObservedComponents = new List<Component>();
val.Synchronization = (ViewSynchronization)0;
if (((Object)obj).name.Contains("Slot Machine") && (Object)(object)obj.GetComponent<SlotMachineRPCHandler>() == (Object)null)
{
obj.AddComponent<SlotMachineRPCHandler>();
}
if (((Object)obj).name.Contains("Wheel Machine") && (Object)(object)obj.GetComponent<WheelMachineRPCHandler>() == (Object)null)
{
obj.AddComponent<WheelMachineRPCHandler>();
}
}
private static void SpinWheel(GameObject wheelMachine, PlayerAvatar avatar)
{
int value = REPOGambling.Instance.wheelSpinCost.Value;
int num = SemiFunc.StatGetRunCurrency();
WheelMachineState component = wheelMachine.GetComponent<WheelMachineState>();
if ((Object)(object)component == (Object)null)
{
return;
}
if (Time.time - component.LastSpinTime < 1.5f)
{
Debug.LogWarning((object)"[REPOGambling] Spin request ignored due to cooldown.");
return;
}
if (component.IsSpinning)
{
PlayWheelSound(GamblingSound.Loss);
Debug.Log((object)"[REPOGambling] Wheel is already spinning!");
return;
}
if (num < value)
{
PlayWheelSound(GamblingSound.Loss);
Debug.Log((object)"[REPOGambling] Not enough money for this action.");
return;
}
Transform val = wheelMachine.transform.Find("Rotator");
if ((Object)(object)val == (Object)null)
{
Debug.LogWarning((object)"[REPOGambling] Rotator transform not found!");
return;
}
REPOGambling.Instance.cachedWheelRotator = val;
PhotonView photonView = avatar.photonView;
component.LastActorNumber = ((photonView != null) ? photonView.OwnerActorNr : (-1));
component.LastSpinTime = Time.time;
component.IsSpinning = true;
SemiFunc.StatSetRunCurrency(num - value);
PlayWheelSound(GamblingSound.Spin);
PlayWheelSound(GamblingSound.WheelLoop);
List<PrizeEntry> prizeEntries = REPOGambling.Instance.prizeEntries;
PrizeEntry prizeEntry = null;
string forcePrizeName = REPOGambling.Instance.devForcePrize.Value?.Trim();
if (!string.IsNullOrEmpty(forcePrizeName))
{
prizeEntry = prizeEntries.FirstOrDefault((PrizeEntry p) => p.name.Equals(forcePrizeName, StringComparison.OrdinalIgnoreCase));
if (prizeEntry != null)
{
Debug.Log((object)("[REPOGambling] Dev config override: Forcing prize '" + prizeEntry.name + "'"));
}
else
{
Debug.LogWarning((object)("[REPOGambling] Dev config: Prize '" + forcePrizeName + "' not found — falling back to random."));
}
}
if (prizeEntry == null)
{
float num2 = prizeEntries.Sum((PrizeEntry p) => p.weight);
float num3 = Random.value * num2;
float num4 = 0f;
foreach (PrizeEntry item in prizeEntries)
{
num4 += item.weight;
if (num3 <= num4)
{
prizeEntry = item;
break;
}
}
}
if (SemiFunc.IsMultiplayer())
{
PhotonView component2 = wheelMachine.GetComponent<PhotonView>();
component2.RPC("RPC_SpinWheel", (RpcTarget)0, new object[3]
{
component2.ViewID,
prizeEntry.name,
avatar.photonView.OwnerActorNr
});
}
else
{
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(SpinWheelCoroutine(val, prizeEntry, value, avatar, component));
}
}
private IEnumerator SpinWheelVisualOnly(Transform wheel, float targetAngle)
{
float spinTime = 6.13f;
float extraRotations = 1080f;
float finalAngle = targetAngle + extraRotations;
float startAngle = wheel.localEulerAngles.z;
float elapsed = 0f;
while (elapsed < spinTime)
{
float t = elapsed / spinTime;
float eased = Mathf.SmoothStep(0f, 1f, t);
float currentZ = Mathf.Lerp(startAngle, finalAngle, eased);
wheel.localEulerAngles = new Vector3(wheel.localEulerAngles.x, wheel.localEulerAngles.y, currentZ);
elapsed += Time.deltaTime;
yield return null;
}
wheel.localEulerAngles = new Vector3(wheel.localEulerAngles.x, wheel.localEulerAngles.y, targetAngle);
}
public static IEnumerator SpinWheelCoroutine(Transform wheel, PrizeEntry prize, int cost, PlayerAvatar avatar, WheelMachineState state)
{
float spinTime = 6.13f;
float elapsed = 0f;
float startAngle = wheel.localEulerAngles.z;
float extraRotations = 1080f;
float targetAngle = prize.angle + extraRotations;
float lastSoundAngle = startAngle;
float soundStep = 35f;
_ = REPOGambling.Instance.clickSound;
while (elapsed < spinTime)
{
float t = elapsed / spinTime;
float eased = Mathf.SmoothStep(0f, 1f, t);
float currentZ = Mathf.Lerp(startAngle, targetAngle, eased);
wheel.localEulerAngles = new Vector3(wheel.localEulerAngles.x, wheel.localEulerAngles.y, currentZ);
if (Mathf.Abs(currentZ - lastSoundAngle) >= soundStep)
{
if (SemiFunc.IsMultiplayer())
{
PhotonView view = ((Component)wheel.parent).gameObject.GetComponent<PhotonView>();
view.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 6 });
}
else
{
AudioSource? obj = wheelAudio;
if (obj != null)
{
obj.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Click));
}
}
lastSoundAngle = currentZ;
}
elapsed += Time.deltaTime;
yield return null;
}
wheel.localEulerAngles = new Vector3(wheel.localEulerAngles.x, wheel.localEulerAngles.y, prize.angle);
HandleWheelPrize(prize, cost, ((Component)wheel).transform.parent, avatar);
state.IsSpinning = false;
}
public static void HandleWheelPrize(PrizeEntry prize, int cost, Transform parent, PlayerAvatar avatar)
{
int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber;
Debug.Log((object)("[REPOGambling] Applying prize '" + prize.name + "' to player " + avatar.playerName));
string text = SemiFunc.PlayerGetSteamID(avatar);
WheelMachineRPCHandler wheelMachineRPCHandler = ((parent != null) ? ((Component)parent).GetComponent<WheelMachineRPCHandler>() : null);
if ((Object)(object)wheelMachineRPCHandler == (Object)null)
{
Debug.LogError((object)"[REPOGambling] RPC handler not found on parent.");
return;
}
switch (prize.name)
{
case "Upgrade":
{
if (!avatar.isLocal)
{
Debug.Log((object)"[REPOGambling] Skipping prize application; this is not the local player.");
break;
}
int num = Random.Range(0, 8);
((MonoBehaviourPun)wheelMachineRPCHandler).photonView.RPC("RPC_ApplyUpgrade", (RpcTarget)2, new object[2] { num, text });
UpgradeAnnounce(num, avatar);
PlayWheelSound(GamblingSound.Win);
break;
}
case "Mystery Prize":
switch (Random.Range(0, 4))
{
case 0:
if (!avatar.isLocal)
{
Debug.Log((object)"[REPOGambling] Skipping prize application; this is not the local player.");
}
else
{
WheelSelfDestruction(avatar);
}
break;
case 1:
if (!avatar.isLocal)
{
Debug.Log((object)"[REPOGambling] Skipping prize application; this is not the local player.");
break;
}
SpecialPrize(parent);
PlayWheelSound(GamblingSound.Death);
break;
case 2:
{
if (!avatar.isLocal)
{
Debug.Log((object)"[REPOGambling] Skipping prize application; this is not the local player.");
break;
}
int num = Random.Range(0, 8);
((MonoBehaviourPun)wheelMachineRPCHandler).photonView.RPC("RPC_ApplyUpgrade", (RpcTarget)2, new object[2] { num, text });
UpgradeAnnounce(num, avatar);
PlayWheelSound(GamblingSound.Win);
break;
}
case 3:
SemiFunc.StatSetRunCurrency(SemiFunc.StatGetRunCurrency() + 2);
PlayWheelSound(GamblingSound.Win);
break;
}
break;
case "Jackpot":
{
int num2 = ((spinTimes <= 2) ? 3 : spinTimes);
SemiFunc.StatSetRunCurrency(SemiFunc.StatGetRunCurrency() + num2);
ResetSpinCount();
PlayWheelSound(GamblingSound.Jackpot);
break;
}
case "Lose":
SemiFunc.StatSetRunCurrency(Mathf.Max(0, SemiFunc.StatGetRunCurrency() - cost));
PlayWheelSound(GamblingSound.Loss);
break;
case "Bankruptcy":
SemiFunc.StatSetRunCurrency(0);
PlayWheelSound(GamblingSound.Loss);
break;
case "Death":
if (!avatar.isLocal)
{
Debug.Log((object)"[REPOGambling] Skipping prize application; this is not the local player.");
break;
}
PlayWheelSound(GamblingSound.Death);
WheelSelfDestruction(avatar);
break;
}
}
private static void PlayWheelSound(GamblingSound sound)
{
Transform cachedWheelRotator = REPOGambling.Instance.cachedWheelRotator;
if ((Object)(object)cachedWheelRotator == (Object)null)
{
Debug.LogWarning((object)"[REPOGambling] Wheel rotator not cached — cannot play sound.");
return;
}
Transform parent = cachedWheelRotator.parent;
GameObject val = ((parent != null) ? ((Component)parent).gameObject : null);
if ((Object)(object)val == (Object)null)
{
Debug.LogWarning((object)"[REPOGambling] Wheel machine not found — cannot play sound.");
return;
}
if (SemiFunc.IsMultiplayer())
{
PhotonView component = val.GetComponent<PhotonView>();
if ((Object)(object)component != (Object)null)
{
component.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { (int)sound });
}
else
{
Debug.LogWarning((object)"[REPOGambling] No PhotonView found on wheel machine for sound RPC.");
}
return;
}
Transform obj = val.transform.Find("Audio Source");
AudioSource val2 = ((obj != null) ? ((Component)obj).GetComponent<AudioSource>() : null);
if ((Object)(object)val2 != (Object)null)
{
AudioClip clip = REPOGambling.Instance.GetClip(sound);
if ((Object)(object)clip != (Object)null)
{
float num = ((sound == GamblingSound.SpinLoop || sound == GamblingSound.WheelLoop) ? 0.7f : 1f);
val2.PlayOneShot(clip, num);
}
else
{
Debug.LogWarning((object)$"[REPOGambling] Missing audio clip for sound: {sound}");
}
}
else
{
Debug.LogWarning((object)"[REPOGambling] Audio Source not found on wheel machine.");
}
}
private static void UpgradeAnnounce(int index, PlayerAvatar avatar)
{
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)avatar == (Object)null) && !avatar.isDisabled)
{
string[] array = new string[8] { "Map Player Count", "Player Energy", "Extra Jump", "Grab Range", "Grab Strength", "Health", "Sprint Speed", "Tumble Launch" };
string text = ((Random.value > 0.5f) ? "Upgraded" : "Just what I wanted, a");
ChatManager instance = ChatManager.instance;
if (!((Object)(object)instance == (Object)null))
{
instance.PossessChatScheduleStart(-1);
instance.PossessChat((PossessChatID)3, text + " " + array[index], 2f, Color.blue, 0f, false, 0, (UnityEvent)null);
instance.PossessChatScheduleEnd();
}
}
}
private static void WheelSelfDestruction(PlayerAvatar avatar)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)avatar == (Object)null) && !avatar.isDisabled)
{
ChatManager instance = ChatManager.instance;
if (!((Object)(object)instance == (Object)null))
{
instance.PossessChatScheduleStart(-1);
string text = REPOGambling.Instance.deathLines[Random.Range(0, REPOGambling.Instance.deathLines.Count)];
float num = 2f;
instance.PossessChat((PossessChatID)3, text, num, Color.red, 0f, true, 2, (UnityEvent)null);
instance.PossessChatScheduleEnd();
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(DelayedDeath(avatar, text.Length, num));
}
}
}
private static void CheaterDestruction(Transform nadeOrigin, int actorNumber)
{
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
if (PhotonNetwork.LocalPlayer.ActorNumber != actorNumber)
{
return;
}
PlayerAvatar val = ChatManager.instance?.playerAvatar;
if (!((Object)(object)val == (Object)null) && !val.isDisabled)
{
ChatManager instance = ChatManager.instance;
if (!((Object)(object)instance == (Object)null))
{
instance.PossessChatScheduleStart(-1);
List<string> list = new List<string>
{
"You thought I wouldn't notice? CHEATER!", "Nice try, cheater.", "Dirty rotten cheater!", "The house always wins. CHEATER!", "Cheater Cheater Cheater Cheater!", "Don't do that AGAIN!", "Slot machine compromised.", "Cheating is a deadly sin.", "You pulled more than a handle. Cheater Detected!", "Tax man doesn't like cheaters",
"Trying to cheat?", "Security breach: life privileges revoked.", "Cheating is a gamble you lost.", "Look at this pathetic cheater!", "Bet tampering: Deleting user!", "Busted for bet tampering."
};
string text = list[Random.Range(0, list.Count)];
float num = 2f;
instance.PossessChat((PossessChatID)3, text, num, Color.red, 0f, true, 2, (UnityEvent)null);
instance.PossessChatScheduleEnd();
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(DelayedDeath(val, text.Length, num));
SpecialPrize(nadeOrigin);
}
}
}
private static IEnumerator DelayedDeath(PlayerAvatar avatar, int messageLength, float typingSpeed)
{
float letterDelay = 0.082f;
float buffer = 1.1f;
float waitTime = ((typingSpeed > 0f) ? ((float)messageLength * letterDelay / typingSpeed) : 0f) + buffer;
yield return (object)new WaitForSeconds(waitTime);
if ((Object)(object)avatar != (Object)null && !avatar.isDisabled)
{
avatar.playerHealth.health = 0;
avatar.playerHealth.Hurt(1, false, -1);
}
}
private static void SpinSlotMachine(GameObject slotMachine, PlayerAvatar avatar)
{
bool flag = SemiFunc.IsMultiplayer();
bool isMasterClient = PhotonNetwork.IsMasterClient;
if (flag && !isMasterClient)
{
Debug.Log((object)"[REPOGambling] Not master client — waiting for RPC.");
return;
}
if (REPOGambling.Instance.slotForceWinChance.Value >= 1f)
{
Debug.LogWarning((object)"[REPOGambling] ForceSlotWinChance was set to 100%. Reverting to default (0.07).");
REPOGambling.Instance.slotForceWinChance.Value = 0.07f;
}
SlotMachineState slotMachineState = slotMachine.GetComponent<SlotMachineState>();
if ((Object)(object)slotMachineState == (Object)null)
{
Debug.LogWarning((object)"[REPOGambling] SlotMachineState missing, adding new.");
slotMachineState = slotMachine.AddComponent<SlotMachineState>();
}
if (slotMachineState.IsSpinning)
{
Debug.Log((object)"[REPOGambling] This slot machine is already spinning!");
return;
}
int num = REPOGambling.Instance.slotBet;
if (num < 2)
{
num = 2;
Debug.LogWarning((object)"[REPOGambling] Slot bet was set lower than 2, readjusting to 2");
}
if (num > REPOGambling.Instance.maxSlotCost.Value)
{
num = REPOGambling.Instance.maxSlotCost.Value;
Debug.LogWarning((object)$"[REPOGambling] Slot bet was set higher than 10, readjusting to {REPOGambling.Instance.maxSlotCost.Value}");
}
int num2 = SemiFunc.StatGetRunCurrency();
Transform obj = slotMachine.transform.Find("Audio Source");
AudioSource val = ((obj != null) ? ((Component)obj).GetComponent<AudioSource>() : null);
if (num2 < num)
{
if (val != null)
{
val.PlayOneShot(REPOGambling.Instance.lossSound);
}
Debug.Log((object)"[REPOGambling] Not enough money for this action.");
return;
}
slotMachineState.IsSpinning = true;
if (SemiFunc.IsMultiplayer())
{
SlotMachineState slotMachineState2 = slotMachineState;
PhotonView photonView = avatar.photonView;
slotMachineState2.lastActorNumber = ((photonView != null) ? photonView.OwnerActorNr : (-1));
}
SemiFunc.StatSetRunCurrency(num2 - num);
if (SemiFunc.IsMultiplayer())
{
PhotonView component = slotMachine.GetComponent<PhotonView>();
component.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 0 });
component.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 1 });
}
else
{
if (val != null)
{
val.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Spin));
}
if (val != null)
{
val.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.SpinLoop), 0.7f);
}
}
Transform val2 = slotMachine.transform.Find("Nade Origin");
if ((Object)(object)val2 == (Object)null)
{
Debug.Log((object)"[REPOGambling] Special Prize Origin could not be found..");
}
float[] array = new float[5] { -45f, -119f, -180f, -255f, -330f };
string[] array2 = new string[5] { "Strawberry", "Spade", "Clove", "7", "Cherry" };
int[] array3 = new int[3];
Transform[] array4 = (Transform[])(object)new Transform[3];
float num3 = Mathf.Clamp(REPOGambling.Instance.slotForceWinChance.Value, 0f, 1f);
bool flag2 = Random.value < REPOGambling.Instance.slotForceWinChance.Value;
bool flag3 = !flag2 && Random.value < REPOGambling.Instance.slotForceLossChance.Value;
int forcedIndexForWinType = GetForcedIndexForWinType(REPOGambling.Instance.slotForceWinType.Value, array2);
for (int i = 0; i < 3; i++)
{
string text = ((i == 0) ? "Roll" : $"Roll{i}");
array4[i] = slotMachine.transform.Find(text);
if ((Object)(object)array4[i] == (Object)null)
{
Debug.LogWarning((object)("[REPOGambling] Could not find " + text + "!"));
array3[i] = -1;
}
else if (flag2)
{
array3[i] = forcedIndexForWinType;
}
else if (flag3)
{
int num4;
do
{
num4 = Random.Range(0, array.Length);
}
while (i > 0 && num4 == array3[i - 1]);
array3[i] = num4;
}
else
{
array3[i] = Random.Range(0, array.Length);
}
}
if (SemiFunc.IsMultiplayer())
{
Debug.Log((object)"Start RPC Condition");
PhotonView component2 = slotMachine.gameObject.GetComponent<PhotonView>();
if ((Object)(object)component2 != (Object)null)
{
Debug.Log((object)((Object)slotMachine).name);
Debug.Log((object)"Passed RPC Condition");
component2.RPC("RPC_SpinSlot", (RpcTarget)0, new object[2] { component2.ViewID, array3 });
}
}
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(SpinAndStop(array4, array3, array, array2, val, slotMachineState, val2));
Debug.Log((object)$"[REPOGambling] Slot Results: {array3[0]}, {array3[1]}, {array3[2]} | ForceWin: {flag2}");
}
private static int GetForcedIndexForWinType(SlotForceWinType type, string[] names)
{
if (1 == 0)
{
}
int result = type switch
{
SlotForceWinType.Jackpot => Array.IndexOf(names, "7"),
SlotForceWinType.Cherry => Array.IndexOf(names, "Cherry"),
SlotForceWinType.Berry => Array.IndexOf(names, "Strawberry"),
SlotForceWinType.Spade => Array.IndexOf(names, "Spade"),
SlotForceWinType.Clove => Array.IndexOf(names, "Clove"),
_ => Random.Range(0, names.Length),
};
if (1 == 0)
{
}
return result;
}
private static void UpdateMachineBet(GameObject slotMachine, bool increase)
{
TextMeshPro component = ((Component)slotMachine.transform.Find("Bet Text")).GetComponent<TextMeshPro>();
if ((Object)(object)component == (Object)null)
{
Debug.LogWarning((object)"[REPOGambling] Could not find TextMesh on slot machine!");
return;
}
Transform obj = slotMachine.transform.Find("Audio Source");
AudioSource val = ((obj != null) ? ((Component)obj).GetComponent<AudioSource>() : null);
SlotMachineState component2 = slotMachine.GetComponent<SlotMachineState>();
if (component2.cheaterCount > 5)
{
component2.cheaterCount = 0;
Transform val2 = slotMachine.transform.Find("Nade Origin");
if ((Object)(object)val2 == (Object)null)
{
Debug.Log((object)"[REPOGambling] Special Prize Origin could not be found..");
}
if (SemiFunc.IsMultiplayer())
{
PhotonView component3 = slotMachine.GetComponent<PhotonView>();
component3.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 8 });
}
else if (val != null)
{
val.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Cheater));
}
if (SemiFunc.IsMultiplayer())
{
int lastActorNumber = component2.lastActorNumber;
if (lastActorNumber != -1)
{
CheaterDestruction(val2, lastActorNumber);
}
else
{
Debug.LogWarning((object)"[REPOGambling] No actor number cached — cheater not punished.");
}
}
else
{
PlayerAvatar.instance.playerHealth.health = 0;
PlayerAvatar.instance.playerHealth.Hurt(1, false, -1);
}
}
if (increase && REPOGambling.Instance.slotBet < REPOGambling.Instance.maxSlotCost.Value)
{
if (component2.IsSpinning)
{
component2.cheaterCount++;
if (SemiFunc.IsMultiplayer())
{
PhotonView component4 = slotMachine.GetComponent<PhotonView>();
component4.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 7 });
}
else if (val != null)
{
val.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Death));
}
return;
}
REPOGambling.Instance.slotBet++;
}
if (!increase && REPOGambling.Instance.slotBet > 2)
{
if (component2.IsSpinning)
{
component2.cheaterCount++;
if (SemiFunc.IsMultiplayer())
{
PhotonView component5 = slotMachine.GetComponent<PhotonView>();
component5.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 7 });
}
else if (val != null)
{
val.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Death));
}
return;
}
REPOGambling.Instance.slotBet--;
}
Debug.Log((object)$"[REPOGambling] Slot bet changed to: {REPOGambling.Instance.slotBet}");
((TMP_Text)component).text = $"Bet: ${REPOGambling.Instance.slotBet}K";
if (SemiFunc.IsMultiplayer())
{
PhotonView component6 = slotMachine.GetComponent<PhotonView>();
if ((Object)(object)component6 != (Object)null)
{
component6.RPC("RPC_UpdateBetText", (RpcTarget)1, new object[2]
{
component6.ViewID,
REPOGambling.Instance.slotBet
});
}
}
}
public static IEnumerator SpinAndStop(Transform[] rolls, int[] results, float[] fruitAngles, string[] fruitNames, AudioSource audio, SlotMachineState state, Transform nadeOrigin)
{
string[] fruitNames2 = fruitNames;
int[] results2 = results;
float spinDuration = 6.38f;
float stopDuration = 0.1f;
float elapsed = 0f;
bool isSpecialCombo = results2.Count((int r) => fruitNames2[r] == "Cherry") == 1 && results2.Count((int r) => fruitNames2[r] == "Spade") == 2;
if (SemiFunc.IsMultiplayer())
{
PhotonView view = ((Component)((Component)rolls[0]).transform.parent).GetComponent<PhotonView>();
view.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 0 });
}
else if (audio != null)
{
audio.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Spin));
}
while (elapsed < spinDuration)
{
foreach (Transform roll in rolls)
{
if (!((Object)(object)roll == (Object)null))
{
float rand = Random.Range(0f, 360f);
roll.localEulerAngles = new Vector3(rand, roll.localEulerAngles.y, roll.localEulerAngles.z);
}
}
elapsed += Time.deltaTime;
yield return null;
}
IEnumerator[] spinCoroutines = new IEnumerator[rolls.Length];
for (int i = 0; i < rolls.Length; i++)
{
if ((Object)(object)rolls[i] != (Object)null && results2[i] != -1)
{
spinCoroutines[i] = SmoothSpinRoll(rolls[i], fruitAngles[results2[i]], stopDuration);
}
}
for (int j = 0; j < spinCoroutines.Length; j++)
{
if (spinCoroutines[j] != null)
{
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(spinCoroutines[j]);
}
}
yield return (object)new WaitForSeconds(stopDuration);
bool allMatch = results2.All((int r) => r == results2[0]) && results2[0] != -1;
bool jackpot = allMatch && fruitNames2[results2[0]] == "7";
(from r in results2
group r by r).ToDictionary((IGrouping<int, int> g) => g.Key, (IGrouping<int, int> g) => g.Count());
bool cloveMatch = allMatch && fruitNames2[results2[0]] == "Clove";
bool spadeMatch = allMatch && fruitNames2[results2[0]] == "Spade";
bool cherryMatch = allMatch && fruitNames2[results2[0]] == "Cherry";
bool berryMatch = allMatch && fruitNames2[results2[0]] == "Strawberry";
float multiplier = 0f;
if (jackpot)
{
multiplier = REPOGambling.Instance.slotRewardJackpotMultiplier.Value;
}
else if (cherryMatch)
{
multiplier = REPOGambling.Instance.slotRewardCherryMatchMultiplier.Value;
}
else if (berryMatch)
{
multiplier = REPOGambling.Instance.slotRewardBerryMatchMultiplier.Value;
}
else if (spadeMatch)
{
multiplier = REPOGambling.Instance.slotRewardSpadeMatchMultiplier.Value;
}
else if (cloveMatch)
{
multiplier = REPOGambling.Instance.slotRewardCloveMatchMultiplier.Value;
}
int payout = Mathf.RoundToInt(multiplier * (float)REPOGambling.Instance.slotBet);
if (isSpecialCombo)
{
SpecialPrize(nadeOrigin);
}
if (payout > 0)
{
SemiFunc.StatSetRunCurrency(SemiFunc.StatGetRunCurrency() + payout);
if (jackpot)
{
ChatManager.instance.PossessChatScheduleStart(-1);
ChatManager.instance.PossessChat((PossessChatID)3, $"Jackpot {payout}k from the slots!", 2f, Color.yellow, 0f, true, 1, (UnityEvent)null);
ChatManager.instance.PossessChatScheduleEnd();
if (SemiFunc.IsMultiplayer())
{
PhotonView view2 = ((Component)((Component)rolls[0]).transform.parent).GetComponent<PhotonView>();
view2.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 5 });
}
else if (audio != null)
{
audio.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Jackpot));
}
}
else if (SemiFunc.IsMultiplayer())
{
PhotonView view3 = ((Component)((Component)rolls[0]).transform.parent).GetComponent<PhotonView>();
view3.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 3 });
}
else if (audio != null)
{
audio.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Win));
}
}
else if (SemiFunc.IsMultiplayer())
{
PhotonView view4 = ((Component)((Component)rolls[0]).transform.parent).GetComponent<PhotonView>();
view4.RPC("RPC_PlaySound", (RpcTarget)0, new object[1] { 4 });
}
else if (audio != null)
{
audio.PlayOneShot(REPOGambling.Instance.GetClip(GamblingSound.Loss));
}
state.IsSpinning = false;
}
private static IEnumerator SmoothSpinRoll(Transform roll, float targetX, float duration)
{
Vector3 start = roll.localEulerAngles;
float startX = start.x;
if (startX > 180f)
{
startX -= 360f;
}
float endX = targetX;
if (endX < startX - 180f)
{
endX += 360f;
}
if (endX > startX + 180f)
{
endX -= 360f;
}
float time = 0f;
while (time < duration)
{
time += Time.deltaTime;
float t = time / duration;
float currentX = Mathf.Lerp(startX, endX, Mathf.SmoothStep(0f, 1f, t));
roll.localEulerAngles = new Vector3(currentX, start.y, start.z);
yield return null;
}
}
private static void SpecialPrize(Transform machineParent)
{
//IL_003d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: 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_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
Transform val = machineParent.Find("Nade Origin");
if ((Object)(object)val == (Object)null)
{
Debug.LogWarning((object)("[REPOGambling] SpecialPrize: 'Nade Origin' not found for machine: " + ((Object)machineParent).name));
return;
}
for (int i = 0; i < 5; i++)
{
Vector3 val2 = val.up * (0.2f + 0.2f * (float)i);
Vector3 val3 = val.position + val2;
GameObject val4 = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate<GameObject>(Resources.Load<GameObject>("Items/Item Grenade Explosive"), val3, Quaternion.identity) : PhotonNetwork.InstantiateRoomObject("Items/Item Grenade Explosive", val3, Quaternion.identity, (byte)0, (object[])null));
Rigidbody component = val4.GetComponent<Rigidbody>();
if ((Object)(object)component != (Object)null)
{
Vector3 val5 = val.up + Random.onUnitSphere;
Vector3 normalized = ((Vector3)(ref val5)).normalized;
float num = Random.Range(1f, 3f);
component.AddForce(normalized * num, (ForceMode)1);
}
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(StartGrenadeTickDelayed(val4));
}
}
private static IEnumerator StartGrenadeTickDelayed(GameObject nade)
{
yield return (object)new WaitForSeconds(0.1f);
ItemGrenade grenade = nade.GetComponent<ItemGrenade>();
if ((Object)(object)grenade != (Object)null)
{
grenade.isSpawnedGrenade = true;
grenade.TickStart();
}
}
public static void ResetSpinCount()
{
spinTimes = 0;
}
}
[HarmonyPatch(typeof(LevelGenerator), "Start")]
public class LevelGeneratorStartPatch
{
[HarmonyPrefix]
public static void Prefix()
{
RunManager instance = RunManager.instance;
if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.levelCurrent != (Object)(object)instance.levelShop))
{
EnvironmentPlacementPatch.ResetSpinCount();
List<GameObject> list = REPOGambling.Instance.LoadModulePrefabsFromBundle();
if (list == null || list.Count == 0)
{
Debug.LogWarning((object)"[REPOGambling] No module prefabs found in bundle.");
}
else if (Random.value <= REPOGambling.Instance.roomSpawnChance.Value)
{
int index = Random.Range(0, list.Count);
GameObject val = list[index];
NetworkPrefabs.RegisterNetworkPrefab("Level/Shop/Modules/" + ((Object)val).name, val);
instance.levelShop.ModulesDeadEnd1.Clear();
instance.levelShop.ModulesDeadEnd1.Add(val);
Debug.Log((object)("[REPOGambling] Injected gambling room: " + ((Object)val).name));
}
else
{
Debug.Log((object)"[REPOGambling] Skipping gambling room this run.");
}
}
}
}
public class PrizeEntry
{
public string name;
public float angle;
public float weight;
public PrizeEntry(string name, float angle, float weight)
{
this.name = name;
this.angle = angle;
this.weight = weight;
}
}
public class SlotMachineState : MonoBehaviour
{
public bool IsSpinning = false;
public int cheaterCount = 0;
public int lastActorNumber = -1;
}
public class WheelMachineState : MonoBehaviour
{
public bool IsSpinning = false;
public int LastActorNumber = -1;
public float LastSpinTime = 0f;
}
public class SlotMachineRPCHandler : MonoBehaviourPun
{
[PunRPC]
public void RPC_SpinSlot(int viewID, int[] results)
{
PhotonView val = PhotonView.Find(viewID);
if ((Object)(object)val == (Object)null)
{
Debug.LogError((object)"[REPOGambling] RPC_SpinSlot: PhotonView not found.");
return;
}
GameObject gameObject = ((Component)val).gameObject;
Transform[] array = (Transform[])(object)new Transform[3];
for (int i = 0; i < 3; i++)
{
string text = ((i == 0) ? "Roll" : $"Roll{i}");
array[i] = gameObject.transform.Find(text);
}
float[] fruitAngles = new float[5] { -45f, -119f, -180f, -255f, -330f };
string[] fruitNames = new string[5] { "Strawberry", "Spade", "Clove", "7", "Cherry" };
Transform obj = gameObject.transform.Find("Audio Source");
AudioSource audio = ((obj != null) ? ((Component)obj).GetComponent<AudioSource>() : null);
SlotMachineState slotMachineState = gameObject.GetComponent<SlotMachineState>();
Transform nadeOrigin = gameObject.transform.Find("Nade Origin");
if ((Object)(object)slotMachineState == (Object)null)
{
slotMachineState = gameObject.AddComponent<SlotMachineState>();
}
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(EnvironmentPlacementPatch.SpinAndStop(array, results, fruitAngles, fruitNames, audio, slotMachineState, nadeOrigin));
Debug.Log((object)"[REPOGambling] RPC_SpinSlot executed across network.");
}
[PunRPC]
public void RPC_UpdateBetText(int viewID, int newBet)
{
PhotonView val = PhotonView.Find(viewID);
if (!((Object)(object)val == (Object)null))
{
GameObject gameObject = ((Component)val).gameObject;
Transform obj = gameObject.transform.Find("Bet Text");
TextMeshPro val2 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshPro>() : null);
if ((Object)(object)val2 != (Object)null)
{
((TMP_Text)val2).text = $"Bet: ${newBet}K";
}
}
}
}
public class WheelMachineRPCHandler : MonoBehaviourPun
{
[PunRPC]
public void RPC_SpinWheel(int viewID, string prizeName, int triggeringActorNumber)
{
string prizeName2 = prizeName;
PhotonView val = PhotonView.Find(viewID);
if ((Object)(object)val == (Object)null)
{
return;
}
Transform val2 = ((Component)val).gameObject.transform.Find("Rotator");
WheelMachineState component = ((Component)val).GetComponent<WheelMachineState>();
PrizeEntry prizeEntry = REPOGambling.Instance.prizeEntries.FirstOrDefault((PrizeEntry p) => p.name == prizeName2);
if (!((Object)(object)component == (Object)null) && prizeEntry != null && !((Object)(object)val2 == (Object)null))
{
PlayerAvatar val3 = FindAvatarByActorNumber(triggeringActorNumber);
if (!((Object)(object)val3 == (Object)null))
{
component.IsSpinning = true;
((MonoBehaviour)REPOGambling.Instance).StartCoroutine(EnvironmentPlacementPatch.SpinWheelCoroutine(val2, prizeEntry, REPOGambling.Instance.wheelSpinCost.Value, val3, component));
}
}
}
private PlayerAvatar FindAvatarByActorNumber(int actorNumber)
{
PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>();
foreach (PlayerAvatar val in array)
{
PhotonView photonView = val.photonView;
if (photonView != null && photonView.OwnerActorNr == actorNumber)
{
Debug.Log((object)$"[REPOGambling] Found avatar for actor {actorNumber}. isLocal={val.isLocal}");
return val;
}
}
return null;
}
[PunRPC]
public void RPC_ApplyUpgrade(int upgradeIndex, string steamID)
{
string steamID2 = steamID;
Action[] array = new Action[8]
{
delegate
{
PunManager.instance.UpgradeMapPlayerCount(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerEnergy(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerExtraJump(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerGrabRange(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerGrabStrength(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerHealth(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerSprintSpeed(steamID2);
},
delegate
{
PunManager.instance.UpgradePlayerTumbleLaunch(steamID2);
}
};
if (upgradeIndex >= 0 && upgradeIndex < array.Length)
{
array[upgradeIndex]();
}
}
}
public class GamblingAudioRPCHandler : MonoBehaviourPun
{
[PunRPC]
public void RPC_PlaySound(int soundInt)
{
AudioClip clip = REPOGambling.Instance.GetClip((GamblingSound)soundInt);
if ((Object)(object)clip == (Object)null)
{
return;
}
Transform val = ((Component)this).transform.Find("Audio Source") ?? ((Component)this).transform.Find("Audio");
AudioSource val2 = ((val != null) ? ((Component)val).GetComponent<AudioSource>() : null);
if ((Object)(object)val2 != (Object)null)
{
val2.outputAudioMixerGroup = AudioManager.instance.SoundMasterGroup;
float num = 1f;
if (soundInt == 1 || soundInt == 2)
{
num = 0.8f;
}
val2.PlayOneShot(clip, num);
}
}
}
public enum GamblingSound
{
Spin,
SpinLoop,
WheelLoop,
Win,
Loss,
Jackpot,
Click,
Death,
Cheater
}
public enum SlotForceWinType
{
Any,
Jackpot,
Cherry,
Berry,
Spade,
Clove
}
}