Decompiled source of Lucky Wheel v0.8.6
UCHLuckyWheel.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; 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 Steamworks; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("UCHLuckyWheel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.8.6.0")] [assembly: AssemblyInformationalVersion("0.8.6")] [assembly: AssemblyProduct("UCHLuckyWheel")] [assembly: AssemblyTitle("UCHLuckyWheel")] [assembly: AssemblyVersion("0.8.6.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UCHLuckyWheel { internal static class LuckyBlock { internal const string BlockName = "Lucky Wheel"; private const string PickableAssetId = "7c1e5a90b3d24f6e8a0d4c2b9e61f357"; private static GameObject holder; internal static Placeable PlaceablePrefab { get; private set; } internal static PickableBlock PickablePrefab { get; private set; } internal static bool Ready { get { if ((Object)(object)PlaceablePrefab != (Object)null) { return (Object)(object)PickablePrefab != (Object)null; } return false; } } internal static bool Ensure() { if (Ready) { return true; } try { return Build(); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Block] Erzeugen des Glücksrad-Blocks fehlgeschlagen: {arg}"); return false; } } private static bool Build() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown PlaceableMetadataList instance = PlaceableMetadataList.Instance; if ((Object)(object)instance == (Object)null || instance.allBlockPrefabs == null) { Plugin.LogVerbose("[Block] Block-Liste des Spiels noch nicht vorhanden"); return false; } string value = Plugin.BaseBlock.Value; Placeable val = null; GameObject[] allBlockPrefabs = instance.allBlockPrefabs; foreach (GameObject val2 in allBlockPrefabs) { Placeable val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Placeable>() : null); if ((Object)(object)val3 != (Object)null && val3.Name == value) { val = val3; break; } } if ((Object)(object)val == (Object)null || (Object)(object)val.PickableBlock == (Object)null) { Plugin.Log.LogError((object)("[Block] Vorlage '" + value + "' nicht gefunden oder ohne PickableBlock")); return false; } holder = new GameObject("UCHLuckyWheel_Prefabs"); holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)holder); GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject, holder.transform); ((Object)val4).name = "LuckyWheelBlock"; Placeable component = val4.GetComponent<Placeable>(); component.Name = "Lucky Wheel"; component.FilterOverride = (Placeable[])(object)new Placeable[1] { val }; SpriteRenderer val5 = ReplaceArt(((Component)component).transform, component.ArtSprites, "LuckyWheelArt", ((Component)component).transform); if ((Object)(object)val5 != (Object)null) { component.ArtSprites = (SpriteRenderer[])(object)new SpriteRenderer[1] { val5 }; } val4.AddComponent<LuckyWheelTrap>(); GameObject obj = Object.Instantiate<GameObject>(((Component)val.PickableBlock).gameObject, holder.transform); ((Object)obj).name = "LuckyWheelBlock_Pick"; PickableBlock component2 = obj.GetComponent<PickableBlock>(); component2.placeablePrefab = component; component.PickableBlock = component2; SetAssetId(obj); DecoratePickable(component2); PlaceablePrefab = component; PickablePrefab = component2; Plugin.Log.LogInfo((object)("[Block] Glücksrad-Block erzeugt (Form-Vorlage '" + value + "' / '" + ((Object)val).name + "', eigene Grafik: " + (((Object)(object)val5 != (Object)null) ? "ja" : "NEIN, Vorlage-Grafik bleibt") + ")")); return true; } private static void SetAssetId(GameObject pickableGo) { //IL_003a: 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) NetworkIdentity component = pickableGo.GetComponent<NetworkIdentity>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogWarning((object)"[Block] PickableBlock ohne NetworkIdentity, online wird der Block nicht funktionieren"); return; } AccessTools.Field(typeof(NetworkIdentity), "m_AssetId").SetValue(component, NetworkHash128.Parse("7c1e5a90b3d24f6e8a0d4c2b9e61f357")); Plugin.LogVerbose($"[Block] Netzwerk-Kennung gesetzt: {component.assetId}"); } private static SpriteRenderer ReplaceArt(Transform parent, SpriteRenderer[] oldArt, string name, Transform colliderRoot) { //IL_0012: 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) //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_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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_01a0: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0070: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0315: 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_0109: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null || oldArt == null) { return null; } SpriteRenderer val = null; bool flag = false; Vector2 val2 = Vector2.zero; Vector2 val3 = Vector2.zero; SpriteRenderer[] array = oldArt; Vector2 val5 = default(Vector2); Vector3 val7 = default(Vector3); foreach (SpriteRenderer val4 in array) { if ((Object)(object)val4 == (Object)null || (Object)(object)val4.sprite == (Object)null) { continue; } val = val ?? val4; Vector2 val6; if ((int)val4.drawMode == 0) { Bounds bounds = val4.sprite.bounds; val5 = Vector2.op_Implicit(((Bounds)(ref bounds)).min); bounds = val4.sprite.bounds; val6 = Vector2.op_Implicit(((Bounds)(ref bounds)).size); } else { val6 = val4.size; Vector2 pivot = val4.sprite.pivot; Rect rect = val4.sprite.rect; ((Vector2)(ref val5))..ctor((0f - pivot.x) / ((Rect)(ref rect)).width * val6.x, (0f - pivot.y) / ((Rect)(ref rect)).height * val6.y); } for (int j = 0; j < 4; j++) { ((Vector3)(ref val7))..ctor(val5.x + (float)(j % 2) * val6.x, val5.y + (float)(j / 2) * val6.y, 0f); Vector2 val8 = Vector2.op_Implicit(parent.InverseTransformPoint(((Component)val4).transform.TransformPoint(val7))); if (!flag) { val2 = (val3 = val8); flag = true; } else { val2 = Vector2.Min(val2, val8); val3 = Vector2.Max(val3, val8); } } } Vector2 val9 = val3 - val2; if (!flag || val9.x < 0.05f || val9.y < 0.05f) { return null; } GameObject val10 = new GameObject(name); val10.layer = ((Component)val).gameObject.layer; val10.transform.SetParent(parent, false); Vector3 val11 = parent.InverseTransformPoint(((Component)val).transform.position); val10.transform.localPosition = new Vector3((val2.x + val3.x) / 2f, (val2.y + val3.y) / 2f, val11.z); SpriteRenderer val12 = val10.AddComponent<SpriteRenderer>(); if (WheelGraphics.TryGetCustomBlock(out var tex, out var body)) { if ((Object)(object)colliderRoot != (Object)null && TryGetSolidRect(colliderRoot, parent, out var min, out var max)) { float num = max.x - min.x; float num2 = ((Rect)(ref body)).width * (float)((Texture)tex).width / num; val12.sprite = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(((Rect)(ref body)).center.x, ((Rect)(ref body)).yMax), num2); val10.transform.localPosition = new Vector3((min.x + max.x) / 2f, max.y, val11.z); Plugin.Log.LogInfo((object)($"[Block] Eigenes Blockbild: feste Fläche {num:F2} x {max.y - min.y:F2}, " + $"Bildkörper {((Rect)(ref body)).width * (float)((Texture)tex).width / num2:F2} x {((Rect)(ref body)).height * (float)((Texture)tex).height / num2:F2}, " + $"ragt {(1f - ((Rect)(ref body)).yMax) * (float)((Texture)tex).height / num2:F2} darüber und {((Rect)(ref body)).yMin * (float)((Texture)tex).height / num2:F2} darunter hinaus")); } else { float num3 = Mathf.Max((float)((Texture)tex).width / val9.x, (float)((Texture)tex).height / val9.y); val12.sprite = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), num3); } ((Object)val12.sprite).name = "LuckyWheelBlockCustom"; } else { val12.sprite = WheelGraphics.GetBlockSprite(val9.x, val9.y); } ((Renderer)val12).sharedMaterial = ((Renderer)val).sharedMaterial; ((Renderer)val12).sortingLayerID = ((Renderer)val).sortingLayerID; ((Renderer)val12).sortingOrder = ((Renderer)val).sortingOrder; array = oldArt; foreach (SpriteRenderer val13 in array) { if ((Object)(object)val13 != (Object)null) { val13.sprite = null; } } Plugin.LogVerbose($"[Block] Grafik '{name}' ersetzt, Fläche {val9.x:F2} x {val9.y:F2}"); return val12; } private static bool TryGetSolidRect(Transform root, Transform space, out Vector2 min, out Vector2 max) { //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_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_000e: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_020f: 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_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: 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) min = (max = Vector2.zero); Transform val = root.Find("SolidCollider"); Collider2D[] componentsInChildren = ((Component)(((Object)(object)val != (Object)null) ? val : root)).GetComponentsInChildren<Collider2D>(true); bool flag = false; Collider2D[] array = componentsInChildren; Vector2 val7 = default(Vector2); foreach (Collider2D val2 in array) { if ((Object)(object)val2 == (Object)null || val2.isTrigger) { continue; } BoxCollider2D val3 = (BoxCollider2D)(object)((val2 is BoxCollider2D) ? val2 : null); Vector2[] array2; if (val3 != null) { Vector2 val4 = val3.size / 2f; array2 = (Vector2[])(object)new Vector2[4] { ((Collider2D)val3).offset - val4, ((Collider2D)val3).offset + val4, ((Collider2D)val3).offset + new Vector2(0f - val4.x, val4.y), ((Collider2D)val3).offset + new Vector2(val4.x, 0f - val4.y) }; } else { PolygonCollider2D val5 = (PolygonCollider2D)(object)((val2 is PolygonCollider2D) ? val2 : null); if (val5 != null) { array2 = val5.points; for (int j = 0; j < array2.Length; j++) { ref Vector2 reference = ref array2[j]; reference += ((Collider2D)val5).offset; } } else { CircleCollider2D val6 = (CircleCollider2D)(object)((val2 is CircleCollider2D) ? val2 : null); if (val6 == null) { continue; } ((Vector2)(ref val7))..ctor(val6.radius, val6.radius); array2 = (Vector2[])(object)new Vector2[2] { ((Collider2D)val6).offset - val7, ((Collider2D)val6).offset + val7 }; } } Vector2[] array3 = array2; foreach (Vector2 val8 in array3) { Vector2 val9 = Vector2.op_Implicit(space.InverseTransformPoint(((Component)val2).transform.TransformPoint(Vector2.op_Implicit(val8)))); if (!flag) { min = (max = val9); flag = true; } else { min = Vector2.Min(min, val9); max = Vector2.Max(max, val9); } } } if (flag) { Plugin.LogVerbose(string.Format("[Block] Feste Fläche aus {0}: x {1:F2}..{2:F2}, y {3:F2}..{4:F2}", ((Object)(object)val != (Object)null) ? "'SolidCollider'" : "allen Collidern", min.x, max.x, min.y, max.y)); } if (flag && max.x - min.x > 0.05f) { return max.y - min.y > 0.05f; } return false; } private static void DecoratePickable(PickableBlock pickable) { //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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00f4: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer val = null; if (pickable.ArtSprites != null) { SpriteRenderer[] artSprites = pickable.ArtSprites; foreach (SpriteRenderer val2 in artSprites) { if ((Object)(object)val2 != (Object)null) { val = val2; break; } } } if (!((Object)(object)val == (Object)null)) { Transform val3 = (((Object)(object)((Component)val).transform.parent != (Object)null) ? ((Component)val).transform.parent : ((Component)pickable).transform); SpriteRenderer val4 = ReplaceArt(val3, pickable.ArtSprites, "LuckyWheelArt", null); SpriteRenderer val5 = (((Object)(object)val4 != (Object)null) ? val4 : val); GameObject val6 = new GameObject("LuckyWheelIcon") { layer = ((Component)val5).gameObject.layer }; val6.transform.SetParent(val3, false); val6.transform.localPosition = ((Component)val5).transform.localPosition + new Vector3(0f, 0.9f, 0f); val6.transform.localScale = Vector3.one * 0.55f; SpriteRenderer val7 = val6.AddComponent<SpriteRenderer>(); val7.sprite = WheelGraphics.GetWheelSprite(LuckyWheelTrap.DeathFieldCount, LuckyWheelTrap.CoinFieldCount); ((Renderer)val7).sharedMaterial = ((Renderer)val5).sharedMaterial; ((Renderer)val7).sortingLayerID = ((Renderer)val5).sortingLayerID; ((Renderer)val7).sortingOrder = ((Renderer)val5).sortingOrder + 10; if ((Object)(object)val4 != (Object)null) { pickable.ArtSprites = (SpriteRenderer[])(object)new SpriteRenderer[2] { val4, val7 }; } else { SpriteRenderer[] artSprites2 = pickable.ArtSprites; SpriteRenderer[] array = (SpriteRenderer[])(object)new SpriteRenderer[artSprites2.Length + 1]; Array.Copy(artSprites2, array, artSprites2.Length); array[artSprites2.Length] = val7; pickable.ArtSprites = array; } } } } internal static class LuckyInventory { private const int GridX = 13; private const int GridY = 17; private const float PageMargin = 0.14f; private static readonly FieldInfo spriteRendersField = AccessTools.Field(typeof(InventoryPage), "spriteRenders"); private static readonly FieldInfo sortingGroupsField = AccessTools.Field(typeof(InventoryPage), "sortingGroups"); internal static void AddTo(InventoryBook book) { //IL_0029: 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_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027f: 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_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.ShowInInventory.Value || (Object)(object)book == (Object)null || book.InventoryPages == null || !LuckyBlock.Ensure()) { return; } InventoryPage val = null; PickableBlock[] array = null; Vector2 val2 = Vector2.zero; float num = -1f; PickableBlock val3 = null; string value = Plugin.BaseBlock.Value; InventoryPage[] inventoryPages = book.InventoryPages; foreach (InventoryPage val4 in inventoryPages) { if ((Object)(object)val4 == (Object)null || !IsInventoryPage(val4) || (Object)(object)val4.pagePaper == (Object)null || ((Object)(object)val4.useThisPrefabInstead != (Object)null && !((Object)val4).name.EndsWith("(Clone)"))) { continue; } if (!WillBeShown(val4)) { Plugin.LogVerbose($"[Inventar] Seite '{((Object)val4).name}' ({val4.pageType}) wird in diesem Modus ausgeblendet, übersprungen"); continue; } PickableBlock[] componentsInChildren = ((Component)val4).GetComponentsInChildren<PickableBlock>(true); if (componentsInChildren.Length == 0) { continue; } PickableBlock[] array2 = componentsInChildren; foreach (PickableBlock val5 in array2) { if ((Object)(object)((Component)val5).GetComponent<LuckyInventoryMarker>() != (Object)null) { Plugin.LogVerbose("[Inventar] Glücksrad-Block ist in diesem Buch schon eingetragen"); return; } if ((Object)(object)val3 == (Object)null && (Object)(object)val5.placeablePrefab != (Object)null && val5.placeablePrefab.Name == value) { val3 = val5; } } Vector2 spot; float num2 = FindFreeSpot(val4, componentsInChildren, out spot); Plugin.LogVerbose($"[Inventar] Seite '{((Object)val4).name}' ({val4.pageType}): {componentsInChildren.Length} Blöcke, größter freier Abstand {num2:F2}"); if (num2 > num) { num = num2; val = val4; array = componentsInChildren; val2 = spot; } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[Inventar] Keine passende Inventar-Seite gefunden, Block wird nicht eingetragen"); return; } PickableBlock val6 = array[0]; PickableBlock val7 = (((Object)(object)val3 != (Object)null) ? val3 : val6); PickableBlock val8 = Object.Instantiate<PickableBlock>(LuckyBlock.PickablePrefab, ((Component)val6).transform.parent); ((Object)val8).name = "LuckyWheelBlock_Inventory"; ((Component)val8).gameObject.AddComponent<LuckyInventoryMarker>(); ((Component)val8).transform.localRotation = ((Component)val6).transform.localRotation; ((Component)val8).transform.localScale = ((Component)val7).transform.localScale; ((Component)val8).transform.position = new Vector3(val2.x, val2.y, ((Component)val6).transform.position.z); int layer = ((Component)val6).gameObject.layer; Transform[] componentsInChildren2 = ((Component)val8).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Component)componentsInChildren2[i]).gameObject.layer = layer; } SpriteRenderer val9 = FirstArt(val6); if ((Object)(object)val9 != (Object)null) { SpriteRenderer[] componentsInChildren3 = ((Component)val8).GetComponentsInChildren<SpriteRenderer>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Renderer)componentsInChildren3[i]).sortingLayerID = ((Renderer)val9).sortingLayerID; } } val.AddPickable((IPickable)(object)val8); (spriteRendersField?.GetValue(val) as List<SpriteRenderer>)?.AddRange(((Component)val8).GetComponentsInChildren<SpriteRenderer>(true)); (sortingGroupsField?.GetValue(val) as List<SortingGroup>)?.AddRange(((Component)val8).GetComponentsInChildren<SortingGroup>(true)); Plugin.Log.LogInfo((object)($"[Inventar] Glücksrad-Block eingetragen auf Seite '{((Object)val).name}' ({val.pageType}) " + $"bei ({val2.x:F2}, {val2.y:F2}), freier Abstand {num:F2}, " + $"Größe von '{((Object)val7).name}', Ebene {LayerMask.LayerToName(layer)} ({layer}), " + "Sortierebene '" + (((Object)(object)val9 != (Object)null) ? ((Renderer)val9).sortingLayerName : "?") + "'")); } private static SpriteRenderer FirstArt(PickableBlock block) { if (block.ArtSprites != null) { SpriteRenderer[] artSprites = block.ArtSprites; foreach (SpriteRenderer val in artSprites) { if ((Object)(object)val != (Object)null) { return val; } } } return ((Component)block).GetComponentInChildren<SpriteRenderer>(true); } private static bool WillBeShown(InventoryPage page) { //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_004e: 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_0060: 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_0080: Invalid comparison between Unknown and I4 if (!((Behaviour)page).isActiveAndEnabled || page.Deactivated) { return false; } GameMode gameMode = GameSettings.GetInstance().GameMode; if ((Object)(object)LobbyManager.instance != (Object)null && !LobbyManager.instance.IsInOnlineGame && page.OnlineOnly) { return false; } if (page.FreeplayOnly && (int)gameMode != 0) { return false; } if (page.BlankLevelOnly) { Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "BlankLevel") { return false; } } if (page.HideInChallengeMode && (int)gameMode == 3) { return false; } AllowedOnPlatform component = ((Component)page).GetComponent<AllowedOnPlatform>(); if (!((Object)(object)component == (Object)null)) { return component.GetAllowed; } return true; } private static bool IsInventoryPage(InventoryPage page) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if ((int)page.pageType >= 3) { return (int)page.pageType <= 11; } return false; } private static float FindFreeSpot(InventoryPage page, PickableBlock[] blocks, out Vector2 spot) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0076: 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_0099: 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_00ad: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(((Component)blocks[0]).transform.position); Vector2 val2 = val; PickableBlock[] array = blocks; foreach (PickableBlock val3 in array) { val = Vector2.Min(val, Vector2.op_Implicit(((Component)val3).transform.position)); val2 = Vector2.Max(val2, Vector2.op_Implicit(((Component)val3).transform.position)); } Bounds bounds = ((Renderer)page.pagePaper).bounds; float num = Mathf.Max(val.x, ((Bounds)(ref bounds)).min.x + ((Bounds)(ref bounds)).size.x * 0.14f); float num2 = Mathf.Min(val2.x, ((Bounds)(ref bounds)).max.x - ((Bounds)(ref bounds)).size.x * 0.14f); float num3 = Mathf.Max(val.y, ((Bounds)(ref bounds)).min.y + ((Bounds)(ref bounds)).size.y * 0.14f); float num4 = Mathf.Min(val2.y, ((Bounds)(ref bounds)).max.y - ((Bounds)(ref bounds)).size.y * 0.14f); if (num2 <= num || num4 <= num3) { num = val.x; num2 = val2.x; num3 = val.y; num4 = val2.y; } Plugin.LogVerbose($"[Inventar] '{((Object)page).name}': Blöcke x {val.x:F1}..{val2.x:F1}, y {val.y:F1}..{val2.y:F1}; " + $"Papier x {((Bounds)(ref bounds)).min.x:F1}..{((Bounds)(ref bounds)).max.x:F1}, y {((Bounds)(ref bounds)).min.y:F1}..{((Bounds)(ref bounds)).max.y:F1}; " + $"nurFreePlay={page.FreeplayOnly} nurOnline={page.OnlineOnly}"); spot = new Vector2((num + num2) / 2f, (num3 + num4) / 2f); float num5 = -1f; Vector2 val4 = default(Vector2); for (int j = 0; j < 13; j++) { for (int k = 0; k < 17; k++) { ((Vector2)(ref val4))..ctor(Mathf.Lerp(num, num2, (float)j / 12f), Mathf.Lerp(num3, num4, (float)k / 16f)); float num6 = float.MaxValue; array = blocks; foreach (PickableBlock val5 in array) { float num7 = Vector2.Distance(val4, Vector2.op_Implicit(((Component)val5).transform.position)); if (num7 < num6) { num6 = num7; } } if (num6 > num5) { num5 = num6; spot = val4; } } } return num5; } } internal class LuckyInventoryMarker : MonoBehaviour { } internal class LuckyNet : MonoBehaviour { [CompilerGenerated] private static class <>O { public static NetworkMessageDelegate <0>__OnSpin; public static NetworkMessageDelegate <1>__OnDenied; public static NetworkMessageDelegate <2>__OnRequest; } private const short MsgRequest = 20101; private const short MsgSpin = 20102; private const short MsgDenied = 20103; private const string PresenceKey = "uchluckywheel"; private const float TickInterval = 1f; private static bool netEnabled; private static string reason = "keine Lobby"; private float nextTick; private string lastError = ""; internal static bool NetEnabled => netEnabled; internal static string Status { get { if (!netEnabled) { return "lokal (" + reason + ")"; } return "abgestimmt mit allen Spielern"; } } private static bool IsHost { get { LobbyManager instance = LobbyManager.instance; if ((Object)(object)instance != (Object)null) { return instance.IsHost; } return false; } } internal static bool IsArbiter { get { if (netEnabled) { return IsHost; } return true; } } internal static bool OnlineWithoutMod { get { LobbyManager instance = LobbyManager.instance; if ((Object)(object)instance != (Object)null && !netEnabled) { if (instance.IsHost) { return instance.CountClients() > 0; } return true; } return false; } } private void Update() { if (Time.unscaledTime < nextTick) { return; } nextTick = Time.unscaledTime + 1f; try { Tick(); } catch (Exception ex) { if (ex.Message != lastError) { lastError = ex.Message; Plugin.Log.LogWarning((object)$"[Net] Fehler bei der Abstimmung, Rad läuft lokal: {ex}"); } SetEnabled(value: false, "Fehler"); } } private void Tick() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00fe: 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_0109: Expected O, but got Unknown LobbyManager instance = LobbyManager.instance; if ((Object)(object)instance == (Object)null || !Plugin.NetSync.Value) { SetEnabled(value: false, ((Object)(object)instance == (Object)null) ? "keine Lobby" : "per Config aus"); return; } CSteamID val = FindSteamLobby(); if (((CSteamID)(ref val)).IsValid() && SteamMatchmaking.GetLobbyMemberData(val, SteamUser.GetSteamID(), "uchluckywheel") != "0.8.6") { SteamMatchmaking.SetLobbyMemberData(val, "uchluckywheel", "0.8.6"); Plugin.LogVerbose("[Net] Version 0.8.6 in der Steam-Lobby eingetragen"); } if (((NetworkManager)instance).client != null) { NetworkClient client = ((NetworkManager)instance).client; object obj = <>O.<0>__OnSpin; if (obj == null) { NetworkMessageDelegate val2 = OnSpin; <>O.<0>__OnSpin = val2; obj = (object)val2; } client.RegisterHandler((short)20102, (NetworkMessageDelegate)obj); NetworkClient client2 = ((NetworkManager)instance).client; object obj2 = <>O.<1>__OnDenied; if (obj2 == null) { NetworkMessageDelegate val3 = OnDenied; <>O.<1>__OnDenied = val3; obj2 = (object)val3; } client2.RegisterHandler((short)20103, (NetworkMessageDelegate)obj2); } if (instance.IsHost && NetworkServer.active) { object obj3 = <>O.<2>__OnRequest; if (obj3 == null) { NetworkMessageDelegate val4 = OnRequest; <>O.<2>__OnRequest = val4; obj3 = (object)val4; } NetworkServer.RegisterHandler((short)20101, (NetworkMessageDelegate)obj3); } SetEnabled(AllHaveMod(val, out var why), why); } private static void SetEnabled(bool value, string why) { if (value != netEnabled || why != reason) { netEnabled = value; reason = why; Plugin.Log.LogInfo((object)("[Net] Glücksrad: " + Status)); } } private static CSteamID FindSteamLobby() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) SteamMatchmaker val = Object.FindObjectOfType<SteamMatchmaker>(); if ((Object)(object)val == (Object)null || val.SteamLobby == null || !((MatchmakingLobby)val.SteamLobby).IsValid()) { return CSteamID.Nil; } return val.SteamLobby.LobbyID; } private static bool AllHaveMod(CSteamID lobby, out string why) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_004c: Unknown result type (might be due to invalid IL or missing references) if (!((CSteamID)(ref lobby)).IsValid()) { why = "keine Steam-Lobby"; return false; } int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(lobby); if (numLobbyMembers < 2) { why = "keine Mitspieler"; return false; } for (int i = 0; i < numLobbyMembers; i++) { CSteamID lobbyMemberByIndex = SteamMatchmaking.GetLobbyMemberByIndex(lobby, i); string lobbyMemberData = SteamMatchmaking.GetLobbyMemberData(lobby, lobbyMemberByIndex, "uchluckywheel"); if (lobbyMemberData != "0.8.6") { string friendPersonaName = SteamFriends.GetFriendPersonaName(lobbyMemberByIndex); why = (string.IsNullOrEmpty(lobbyMemberData) ? ("'" + friendPersonaName + "' hat den Mod nicht") : ("'" + friendPersonaName + "' hat Version " + lobbyMemberData + " statt 0.8.6")); return false; } } why = ""; return true; } internal static void SendRequest(int blockId, uint charNetId) { LobbyManager instance = LobbyManager.instance; if ((Object)(object)instance != (Object)null && ((NetworkManager)instance).client != null) { ((NetworkManager)instance).client.Send((short)20101, (MessageBase)(object)new WheelMsg { BlockId = blockId, CharNetId = charNetId }); } } internal static void BroadcastSpin(int blockId, uint charNetId, int level, int field, float duration) { if (!netEnabled || !IsHost) { return; } WheelMsg wheelMsg = new WheelMsg { BlockId = blockId, CharNetId = charNetId, Level = level, Field = field, Duration = duration }; foreach (NetworkConnection connection in NetworkServer.connections) { if (connection != null && connection.hostId != -1) { connection.Send((short)20102, (MessageBase)(object)wheelMsg); } } } private static void OnRequest(NetworkMessage netMsg) { WheelMsg wheelMsg = netMsg.ReadMessage<WheelMsg>(); if (!LuckyWheelTrap.HostHandleRequest(wheelMsg.BlockId, wheelMsg.CharNetId)) { netMsg.conn.Send((short)20103, (MessageBase)(object)wheelMsg); } } private static void OnSpin(NetworkMessage netMsg) { WheelMsg wheelMsg = netMsg.ReadMessage<WheelMsg>(); if (!IsHost) { LuckyWheelTrap.OnSpinFromHost(wheelMsg.BlockId, wheelMsg.CharNetId, wheelMsg.Level, wheelMsg.Field, wheelMsg.Duration); } } private static void OnDenied(NetworkMessage netMsg) { WheelMsg wheelMsg = netMsg.ReadMessage<WheelMsg>(); LuckyWheelTrap.OnDeniedByHost(wheelMsg.BlockId, wheelMsg.CharNetId); } } internal class WheelMsg : MessageBase { public int BlockId; public uint CharNetId; public int Level; public int Field; public float Duration; public override void Serialize(NetworkWriter writer) { writer.Write(BlockId); writer.Write(CharNetId); writer.Write(Level); writer.Write(Field); writer.Write(Duration); } public override void Deserialize(NetworkReader reader) { BlockId = reader.ReadInt32(); CharNetId = reader.ReadUInt32(); Level = reader.ReadInt32(); Field = reader.ReadInt32(); Duration = reader.ReadSingle(); } } internal enum WheelOutcome { Death, Coin, Nothing } internal class LuckyWheelTrap : MonoBehaviour { private enum State { Idle, Requesting, Spinning, Cooldown } internal const int FieldCount = 4; private const string DeathCause = "LuckyWheel"; private const float CooldownSeconds = 1f; private const float RequestTimeout = 1.5f; private const float RetryDelay = 0.4f; private const float CharacterScanInterval = 0.5f; private const int FullTurns = 5; private const float PointerScale = 1.5f; private const float PointerOverlap = 0.05f; internal static readonly List<LuckyWheelTrap> All = new List<LuckyWheelTrap>(); private static readonly FieldRef<Character, bool> dancingField = AccessTools.FieldRefAccess<Character, bool>("dancing"); private static Character[] characters = (Character[])(object)new Character[0]; private static float nextCharacterScan; private Placeable block; private GameObject visualRoot; private Transform wheel; private int builtLayout = -1; private State state; private Character captive; private float spinStart; private float spinDuration; private float endAngle; private int result; private float cooldownUntil; private Character pending; private float requestDeadline; private float retryAfter; private float nextWaitLog; private int spinLevel; private int spinDeathFields = 1; private int spinCoinFields = 1; private SpriteRenderer pointerRenderer; private float rim = 1f; private Character immune; private static readonly Dictionary<Character, int> spinsThisRound = new Dictionary<Character, int>(); internal static int DeathFieldCount => Mathf.Clamp(Plugin.DeathFields.Value, 0, 4); internal static int CoinFieldCount => Mathf.Clamp(Plugin.CoinFields.Value, 0, 4 - DeathFieldCount); private static bool IsDancing(Character c) { return dancingField.Invoke(c); } internal static int RiskLevelOf(Character c) { if (!Plugin.RiskLevels.Value || (Object)(object)c == (Object)null) { return 0; } spinsThisRound.TryGetValue(c, out var value); return Mathf.Min(value, Mathf.Max(0, Plugin.MaxRiskLevel.Value)); } internal static int DeathFieldsAt(int level) { if (level != 0) { return Mathf.Min(DeathFieldCount + level, 3); } return DeathFieldCount; } internal static int CoinFieldsAt(int level) { return Mathf.Clamp(Plugin.CoinFields.Value, 0, 4 - DeathFieldsAt(level)); } internal static int CoinPayoutAt(int level) { return 1 + level; } internal static void ResetRiskLevels() { if (spinsThisRound.Count > 0) { spinsThisRound.Clear(); Plugin.LogVerbose("[Wheel] Risiko-Stufen zurückgesetzt"); } } private WheelOutcome OutcomeOf(int field) { if (field < spinDeathFields) { return WheelOutcome.Death; } if (field >= spinDeathFields + spinCoinFields) { return WheelOutcome.Nothing; } return WheelOutcome.Coin; } private void Awake() { block = ((Component)this).GetComponent<Placeable>(); All.Add(this); BuildVisual(); Plugin.LogVerbose("[Wheel] Falle an Block '" + ((Object)this).name + "' angebracht"); } private void OnEnable() { if ((Object)(object)visualRoot != (Object)null) { visualRoot.SetActive(true); } } private void OnDisable() { if ((Object)(object)visualRoot != (Object)null) { visualRoot.SetActive(false); } } private void OnDestroy() { All.Remove(this); ReleasePending(); ReleaseCaptive("Block entfernt"); if ((Object)(object)visualRoot != (Object)null) { Object.Destroy((Object)(object)visualRoot); } } private void BuildVisual() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_004a: 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_0066: 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_0076: Unknown result type (might be due to invalid IL or missing references) visualRoot = new GameObject("LuckyWheelVisual"); GameObject val = new GameObject("Wheel"); val.transform.SetParent(visualRoot.transform, false); wheel = val.transform; SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); GameObject val3 = new GameObject("Pointer"); val3.transform.SetParent(visualRoot.transform, false); val3.transform.localScale = Vector3.one * 1.5f; SpriteRenderer val4 = val3.AddComponent<SpriteRenderer>(); val4.sprite = WheelGraphics.PointerSprite; pointerRenderer = val4; SpriteRenderer componentInChildren = ((Component)this).GetComponentInChildren<SpriteRenderer>(); if ((Object)(object)componentInChildren != (Object)null) { ((Renderer)val2).sortingLayerID = ((Renderer)componentInChildren).sortingLayerID; ((Renderer)val4).sortingLayerID = ((Renderer)componentInChildren).sortingLayerID; } int num = (((Object)(object)componentInChildren != (Object)null) ? ((Renderer)componentInChildren).sortingOrder : 0); ((Renderer)val2).sortingOrder = num + 2; ((Renderer)val4).sortingOrder = num + 3; ShowLevel(0); UpdateVisualPosition(); } private void ShowLevel(int level) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) spinLevel = level; spinDeathFields = DeathFieldsAt(level); spinCoinFields = CoinFieldsAt(level); int num = spinDeathFields * 10 + spinCoinFields; if (num != builtLayout && (Object)(object)wheel != (Object)null) { builtLayout = num; Sprite wheelSprite = WheelGraphics.GetWheelSprite(spinDeathFields, spinCoinFields); ((Component)wheel).GetComponent<SpriteRenderer>().sprite = wheelSprite; rim = WheelGraphics.RimFraction(wheelSprite); } if ((Object)(object)pointerRenderer != (Object)null) { pointerRenderer.color = (Color)(level switch { 1 => new Color(1f, 0.6f, 0.1f), 0 => Color.white, _ => new Color(1f, 0.2f, 0.2f), }); } } private void UpdateVisualPosition() { //IL_0010: 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_001d: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)visualRoot == (Object)null)) { Bounds blockBounds = GetBlockBounds(); float num = Mathf.Max(0.2f, ((Bounds)(ref blockBounds)).size.x * Plugin.WheelSize.Value); float num2 = 0.9f * rim; visualRoot.transform.localScale = Vector3.one * (num / num2); float num3 = ((((Component)this).transform.lossyScale.x < 0f) ? (-1f) : 1f); float num4 = ((Bounds)(ref blockBounds)).center.x + num3 * WheelGraphics.WheelOffsetFraction * ((Bounds)(ref blockBounds)).size.x; visualRoot.transform.position = new Vector3(num4, ((Bounds)(ref blockBounds)).max.y + num + Plugin.WheelHeight.Value, ((Component)this).transform.position.z); if ((Object)(object)pointerRenderer != (Object)null) { ((Component)pointerRenderer).transform.localPosition = new Vector3(0f, num2 - 0.05f, 0f); } } } private Bounds GetBlockBounds() { //IL_000a: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(((Component)this).transform.position, Vector3.zero); Collider2D[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider2D>(); foreach (Collider2D val in componentsInChildren) { if (!val.isTrigger && ((Behaviour)val).enabled) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return bounds; } internal static bool InPlay() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 LobbyManager instance = LobbyManager.instance; GameControl val = (((Object)(object)instance != (Object)null) ? instance.CurrentGameController : null); if ((Object)(object)val != (Object)null) { if ((int)val.Phase != 2) { return (int)val.Phase == 4; } return true; } return false; } private static void RefreshCharacters() { if (Time.time >= nextCharacterScan) { nextCharacterScan = Time.time + 0.5f; characters = Object.FindObjectsOfType<Character>(); } } private void FixedUpdate() { //IL_0031: 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_004b: 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_00cb: Unknown result type (might be due to invalid IL or missing references) if (state != State.Idle || (Object)(object)block == (Object)null || !block.Placed || !InPlay()) { return; } RefreshCharacters(); Bounds blockBounds = GetBlockBounds(); if ((Object)(object)immune != (Object)null && (!IsOverBlock(immune, blockBounds) || (Plugin.RequireDance.Value && ((NetworkBehaviour)immune).hasAuthority && !IsDancing(immune)))) { immune = null; } if (Time.time < retryAfter) { return; } Character[] array = characters; foreach (Character val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)immune) && CanCapture(val) && IsOverBlock(val, blockBounds)) { Character val2 = OtherOnBlock(val, blockBounds); if (!((Object)(object)val2 != (Object)null)) { TryCapture(val); break; } if (Time.time >= nextWaitLog) { nextWaitLog = Time.time + 2f; Plugin.LogVerbose($"[Wheel] '{((Object)val).name}' wartet: '{((Object)val2).name}' steht noch auf Block id={block.ID}"); } } } } private static bool CanCapture(Character c) { if (((NetworkBehaviour)c).hasAuthority && ((Behaviour)c).isActiveAndEnabled && !c.Dead && !c.Frozen && !c.Waiting && !c.Success && !c.isGhost && c.OnGround) { if (Plugin.RequireDance.Value) { return IsDancing(c); } return true; } return false; } private static bool IsOverBlock(Character c, Bounds b) { //IL_0026: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_004e: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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) Vector3 val = (((Object)(object)c.Feet != (Object)null) ? ((Component)c.Feet).transform.position : ((Component)c).transform.position); if (val.x >= ((Bounds)(ref b)).min.x - 0.1f && val.x <= ((Bounds)(ref b)).max.x + 0.1f && val.y >= ((Bounds)(ref b)).max.y - 0.25f) { return val.y <= ((Bounds)(ref b)).max.y + 0.5f; } return false; } private static Character OtherOnBlock(Character c, Bounds b) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) Character[] array = characters; foreach (Character val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)c && ((Behaviour)val).isActiveAndEnabled && !val.Dead && !val.isGhost && val.OnGround && IsOverBlock(val, b)) { return val; } } return null; } private void TryCapture(Character c) { //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) if (LuckyNet.IsArbiter) { HostAccept(c); return; } pending = c; c.Freeze(false, true, false); state = State.Requesting; requestDeadline = Time.unscaledTime + 1.5f; int iD = block.ID; NetworkInstanceId netId = ((NetworkBehaviour)c).netId; LuckyNet.SendRequest(iD, ((NetworkInstanceId)(ref netId)).Value); Plugin.LogVerbose($"[Wheel] '{((Object)c).name}' auf Block id={block.ID}: Anfrage an den Host"); } internal static bool HostHandleRequest(int blockId, uint charNetId) { LuckyWheelTrap luckyWheelTrap = FindByBlockId(blockId); Character val = FindCharacter(charNetId); if ((Object)(object)luckyWheelTrap == (Object)null || (Object)(object)val == (Object)null) { Plugin.LogVerbose($"[Wheel] Anfrage abgelehnt: Block id={blockId} oder Figur {charNetId} unbekannt"); return false; } RefreshCharacters(); string text = luckyWheelTrap.RejectReason(val); if (text != null) { Plugin.LogVerbose($"[Wheel] Anfrage von '{((Object)val).name}' für Block id={blockId} abgelehnt: {text}"); return false; } luckyWheelTrap.HostAccept(val); return true; } private string RejectReason(Character c) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (state != State.Idle) { return "Rad ist beschäftigt"; } if ((Object)(object)block == (Object)null || !block.Placed || !InPlay()) { return "Block nicht aktiv"; } if (c.Dead) { return "Figur ist tot"; } Character val = OtherOnBlock(c, GetBlockBounds()); if (!((Object)(object)val != (Object)null)) { return null; } return "'" + ((Object)val).name + "' steht noch drauf"; } private void HostAccept(Character c) { //IL_004c: 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) int level = RiskLevelOf(c); spinsThisRound.TryGetValue(c, out var value); spinsThisRound[c] = value + 1; int field = Random.Range(0, 4); float duration = Mathf.Max(0.5f, Plugin.SpinDuration.Value); int iD = block.ID; NetworkInstanceId netId = ((NetworkBehaviour)c).netId; LuckyNet.BroadcastSpin(iD, ((NetworkInstanceId)(ref netId)).Value, level, field, duration); BeginSpin(c, level, field, duration); } internal static void OnSpinFromHost(int blockId, uint charNetId, int level, int field, float duration) { LuckyWheelTrap luckyWheelTrap = FindByBlockId(blockId); if ((Object)(object)luckyWheelTrap == (Object)null) { Plugin.LogVerbose($"[Wheel] Drehung für unbekannten Block id={blockId} erhalten"); return; } Character val = FindCharacter(charNetId); if ((Object)(object)luckyWheelTrap.pending != (Object)null && (Object)(object)luckyWheelTrap.pending != (Object)(object)val) { luckyWheelTrap.ReleasePending(); } luckyWheelTrap.pending = null; luckyWheelTrap.BeginSpin(val, level, field, duration); } internal static void OnDeniedByHost(int blockId, uint charNetId) { //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) LuckyWheelTrap luckyWheelTrap = FindByBlockId(blockId); if ((Object)(object)luckyWheelTrap != (Object)null && luckyWheelTrap.state == State.Requesting && (Object)(object)luckyWheelTrap.pending != (Object)null) { NetworkInstanceId netId = ((NetworkBehaviour)luckyWheelTrap.pending).netId; if (((NetworkInstanceId)(ref netId)).Value == charNetId) { Plugin.LogVerbose($"[Wheel] Host hat die Anfrage für Block id={blockId} abgelehnt"); luckyWheelTrap.ReleasePending(); luckyWheelTrap.state = State.Idle; luckyWheelTrap.retryAfter = Time.time + 0.4f; } } } private void ReleasePending() { Character val = pending; pending = null; if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).hasAuthority && val.Frozen) { val.Unfreeze(); } } private static LuckyWheelTrap FindByBlockId(int id) { foreach (LuckyWheelTrap item in All) { if ((Object)(object)item != (Object)null && (Object)(object)item.block != (Object)null && item.block.ID == id) { return item; } } return null; } private static Character FindCharacter(uint netId) { //IL_0008: 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) NetworkInstanceId val = default(NetworkInstanceId); ((NetworkInstanceId)(ref val))..ctor(netId); GameObject val2 = ClientScene.FindLocalObject(val); if ((Object)(object)val2 == (Object)null && NetworkServer.active) { val2 = NetworkServer.FindLocalObject(val); } if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.GetComponent<Character>(); } private void BeginSpin(Character c, int level, int field, float duration) { captive = c; if ((Object)(object)c != (Object)null && ((NetworkBehaviour)c).hasAuthority && !c.Frozen) { c.Freeze(false, true, false); } StartSpin(field, level, duration); Plugin.Log.LogInfo((object)(string.Format("[Wheel] '{0}' gefangen auf Block id={1}; Risiko-Stufe {2} ", ((Object)(object)c != (Object)null) ? ((Object)c).name : "?", block.ID, level) + $"({spinDeathFields} Tod, {spinCoinFields} Münze x{CoinPayoutAt(level)}); Ergebnis Feld {result} " + $"({OutcomeOf(result)}), Drehdauer {spinDuration:F1}s, eigene Figur: {(Object)(object)c != (Object)null && ((NetworkBehaviour)c).hasAuthority}, {LuckyNet.Status}")); } internal void DemoSpin() { if (state == State.Idle) { captive = null; StartSpin(Random.Range(0, 4), 0, Mathf.Max(0.5f, Plugin.SpinDuration.Value)); Plugin.Log.LogInfo((object)$"[Wheel] Demo-Drehung, Ergebnis Feld {result} ({OutcomeOf(result)})"); } } private void StartSpin(int field, int level, float duration) { ShowLevel(level); result = field; spinDuration = duration; spinStart = Time.time; endAngle = 45f - 90f * (float)field + 1800f; state = State.Spinning; } private void Update() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) UpdateVisualPosition(); if (state == State.Requesting) { if (Time.unscaledTime >= requestDeadline || (Object)(object)pending == (Object)null || pending.Dead || !InPlay()) { Plugin.LogVerbose($"[Wheel] Keine Antwort vom Host für Block id={block.ID}, Figur freigegeben"); ReleasePending(); state = State.Idle; retryAfter = Time.time + 0.4f; } } else if (state == State.Cooldown) { if (Time.time >= cooldownUntil) { state = State.Idle; ShowLevel(0); } } else if (state == State.Spinning) { float num = Mathf.Clamp01((Time.time - spinStart) / spinDuration); float num2 = 1f - (1f - num) * (1f - num) * (1f - num); wheel.localEulerAngles = new Vector3(0f, 0f, endAngle * num2); if ((Object)(object)captive != (Object)null && (captive.Dead || !InPlay())) { ReleaseCaptive(captive.Dead ? "Figur ist anderweitig gestorben" : "Runde vorbei"); EnterCooldown(); } else if (num >= 1f) { Finish(); } } } private void Finish() { Character val = captive; WheelOutcome wheelOutcome = OutcomeOf(result); if ((Object)(object)val != (Object)null) { if (wheelOutcome == WheelOutcome.Death) { captive = null; if (((NetworkBehaviour)val).hasAuthority) { val.Unfreeze(); int num = (((Object)(object)block != (Object)null) ? block.placedByPlayerNumber : 0); Plugin.Log.LogInfo((object)$"[Wheel] Todesfeld: '{((Object)val).name}' stirbt (KillCharacter, verursacht von Spieler {num})"); val.KillCharacter("LuckyWheel", true, num, true); } } else { ReleaseCaptive((wheelOutcome == WheelOutcome.Coin) ? "Münzfeld" : "neutrales Feld"); if (wheelOutcome == WheelOutcome.Coin) { WheelCoins.Grant(val, CoinPayoutAt(spinLevel)); } } } EnterCooldown(); } private void ReleaseCaptive(string reason) { //IL_0050: 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) Character val = captive; captive = null; if ((Object)(object)val == (Object)null) { return; } immune = val; if (((NetworkBehaviour)val).hasAuthority) { if (val.Frozen) { val.Unfreeze(); } if (!val.Dead && Plugin.ReleaseImpulse.Value > 0f) { val.AddImpulse(Vector2.up * Plugin.ReleaseImpulse.Value, 0.1f, true); } Plugin.Log.LogInfo((object)("[Wheel] '" + ((Object)val).name + "' freigegeben (" + reason + ")")); } } private void EnterCooldown() { state = State.Cooldown; cooldownUntil = Time.time + 1f; } } [BepInPlugin("mpb27.uch.luckywheel", "UCH Lucky Wheel", "0.8.6")] public class Plugin : BaseUnityPlugin { public const string Guid = "mpb27.uch.luckywheel"; public const string Name = "UCH Lucky Wheel"; public const string Version = "0.8.6"; internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<bool> ModEnabled; internal static ConfigEntry<float> SpinDuration; internal static ConfigEntry<int> DeathFields; internal static ConfigEntry<KeyboardShortcut> DebugHotkey; internal static ConfigEntry<bool> VerboseLog; internal static ConfigEntry<float> ReleaseImpulse; internal static ConfigEntry<int> CoinFields; internal static ConfigEntry<bool> CoinNeedsGoal; internal static ConfigEntry<bool> RiskLevels; internal static ConfigEntry<int> MaxRiskLevel; internal static ConfigEntry<string> BaseBlock; internal static ConfigEntry<float> PartyBoxChance; internal static ConfigEntry<bool> ShowInInventory; internal static ConfigEntry<bool> NetSync; internal static ConfigEntry<float> WheelHeight; internal static ConfigEntry<float> WheelSize; internal static ConfigEntry<bool> RequireDance; private Harmony harmony; private void Awake() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Expected O, but got Unknown //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Expected O, but got Unknown //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Expected O, but got Unknown //IL_041b: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Mod an/aus. Aus = es wird nichts gepatcht."); SpinDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Wheel", "SpinDuration", 3f, new ConfigDescription("Wie lange das Rad dreht (Sekunden).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>())); DeathFields = ((BaseUnityPlugin)this).Config.Bind<int>("Wheel", "DeathFields", 1, new ConfigDescription("Anzahl Todesfelder von 4.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>())); CoinFields = ((BaseUnityPlugin)this).Config.Bind<int>("Wheel", "CoinFields", 1, new ConfigDescription("Anzahl Muenzfelder von 4 (gruen). Todesfelder haben Vorrang, der Rest ist neutral.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>())); CoinNeedsGoal = ((BaseUnityPlugin)this).Config.Bind<bool>("Wheel", "CoinNeedsGoal", true, "true: Die Muenze zaehlt wie eine echte erst im Ziel und geht beim Tod verloren. false: Der Muenzpunkt wird sofort gutgeschrieben."); RiskLevels = ((BaseUnityPlugin)this).Config.Bind<bool>("Wheel", "RiskLevels", true, "Risiko-Stufen: Jede weitere Drehung desselben Spielers in einer Runde hat ein Todesfeld mehr (hoechstens 3) und bringt eine Muenze mehr."); MaxRiskLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Wheel", "MaxRiskLevel", 2, new ConfigDescription("Hoechste Risiko-Stufe (0 = erste Drehung).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); BaseBlock = ((BaseUnityPlugin)this).Config.Bind<string>("Block", "ShapeTemplate", "Triple Block", "Form-Vorlage fuer den Gluecksrad-Block: bestimmt Groesse und Kollision, nicht das Aussehen (Feld 'Name' aus der Block-Liste: 'Triple Block', '4-Block', '5-Block', '6-Block'). Das Blockbild wird auf die Breite der Vorlage gezogen; bei schmalen Vorlagen ist die gezeichnete Bank flacher als der feste Block."); RequireDance = ((BaseUnityPlugin)this).Config.Bind<bool>("Wheel", "RequireDance", true, "true: Das Rad dreht nur, wenn man auf dem Block tanzt. false: Es loest schon aus, wenn man darauf landet."); WheelSize = ((BaseUnityPlugin)this).Config.Bind<float>("Wheel", "SizeRelativeToBlock", 0.155f, new ConfigDescription("Radius des sichtbaren Rads als Anteil der Blockbreite. 0.155 bei einem 3 breiten Block = Rad mit gut 0.9 Einheiten Durchmesser.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); WheelHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Wheel", "HeightAboveBlock", 0f, new ConfigDescription("Abstand zwischen Block-Oberkante und Unterkante des Rads. 0 = das Rad steht auf dem Block, negativ = es sinkt zwischen die Stuetzen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1f, 4f), Array.Empty<object>())); PartyBoxChance = ((BaseUnityPlugin)this).Config.Bind<float>("Block", "PartyBoxDropChance", 0.125f, new ConfigDescription("Wahrscheinlichkeit pro Runde, dass der Gluecksrad-Block in der Party-Box liegt. 0.125 = etwa jede 8. Runde, 1 = immer, 0 = nie.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); if (Mathf.Approximately(PartyBoxChance.Value, 0.0625f) || Mathf.Approximately(PartyBoxChance.Value, 0.1f)) { PartyBoxChance.Value = 0.125f; } ShowInInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("Block", "ShowInInventory", true, "Den Gluecksrad-Block ins Inventar-Buch eintragen (Creative- und Free-Play-Modus)."); NetSync = ((BaseUnityPlugin)this).Config.Bind<bool>("Online", "Sync", true, "Online stimmt der Host ab, wer gefangen wird und was das Rad zeigt. Greift nur, wenn alle Spieler der Lobby den Mod in derselben Version haben."); ReleaseImpulse = ((BaseUnityPlugin)this).Config.Bind<float>("Wheel", "ReleaseLaunchStrength", 0f, new ConfigDescription("Schub nach oben bei Freigabe. 0 = kein Schub, die Figur bleibt einfach stehen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>())); DebugHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "Hotkey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Debug-Taste: Demo-Drehung aller Fallen; ohne Fallen schreibt sie die Block-Liste ins Log."); VerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLog", true, "Ausfuehrliches Logging."); if (!ModEnabled.Value) { Log.LogInfo((object)"UCH Lucky Wheel 0.8.6 geladen, aber per Config deaktiviert."); return; } harmony = new Harmony("mpb27.uch.luckywheel"); harmony.PatchAll(typeof(Plugin).Assembly); ((Component)this).gameObject.AddComponent<WheelCoins>(); ((Component)this).gameObject.AddComponent<LuckyNet>(); int num = 0; foreach (MethodBase patchedMethod in harmony.GetPatchedMethods()) { _ = patchedMethod; num++; } Log.LogInfo((object)(string.Format("{0} {1} geladen, {2} Methode(n) gepatcht. ", "UCH Lucky Wheel", "0.8.6", num) + $"SpinDuration={SpinDuration.Value}s DeathFields={DeathFields.Value} Hotkey={DebugHotkey.Value}")); } private void Update() { //IL_0011: 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) if (!ModEnabled.Value) { return; } KeyboardShortcut value = DebugHotkey.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { return; } if (LuckyWheelTrap.All.Count > 0) { foreach (LuckyWheelTrap item in LuckyWheelTrap.All) { item.DemoSpin(); } return; } DumpBlockList(); } private static void DumpBlockList() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) PlaceableMetadataList instance = PlaceableMetadataList.Instance; if ((Object)(object)instance == (Object)null) { Log.LogInfo((object)"[Debug] PlaceableMetadataList noch nicht vorhanden (erst im Spiel/Lobby verfuegbar)."); return; } Log.LogInfo((object)$"[Debug] allBlockPrefabs: {instance.allBlockPrefabs.Length}, extraBlocks: {instance.extraBlocks.Length}"); for (int i = 0; i < instance.allBlockPrefabs.Length; i++) { GameObject val = instance.allBlockPrefabs[i]; Placeable val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Placeable>() : null); Log.LogInfo((object)(((Object)(object)val2 == (Object)null) ? string.Format("[Debug] {0}: (kein Placeable) '{1}'", i, ((Object)(object)val != (Object)null) ? ((Object)val).name : "null") : ($"[Debug] {i}: prefab='{((Object)val).name}' Name='{val2.Name}' typ={((object)val2).GetType().Name} " + $"rarity={val2.BaseRarity} setPiece={val2.isSetPiece} pickable={(Object)(object)val2.PickableBlock != (Object)null}"))); } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } internal static void LogVerbose(string msg) { if (VerboseLog.Value) { Log.LogInfo((object)msg); } } } internal class WheelCoins : MonoBehaviour { private class Carried { public int Count; public readonly List<GameObject> Visuals = new List<GameObject>(); } private const int MaxShown = 9; private const float Spacing = 0.42f; private static readonly Dictionary<Character, Carried> carried = new Dictionary<Character, Carried>(); private static readonly List<Character> done = new List<Character>(); internal static void Grant(Character c, int count) { if ((Object)(object)c == (Object)null || count <= 0) { return; } if (!Plugin.CoinNeedsGoal.Value) { Award(c, count, "sofort"); return; } if (!carried.TryGetValue(c, out var value)) { value = new Carried(); carried[c] = value; } value.Count += count; while (value.Visuals.Count < Mathf.Min(value.Count, 9)) { value.Visuals.Add(CreateVisual(c)); } Plugin.Log.LogInfo((object)$"[Coin] '{((Object)c).name}' trägt jetzt {value.Count} Glücksrad-Münze(n); Punkt gibt es im Ziel (eigene Figur: {((NetworkBehaviour)c).hasAuthority})"); } private static void Award(Character c, int count, string when) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (((NetworkBehaviour)c).hasAuthority) { ScoreKeeper instance = ScoreKeeper.Instance; for (int i = 0; i < count; i++) { bool flag = instance != null && instance.AwardPoint(new PointBlock((pointBlockType)7, c.networkNumber), false); Plugin.Log.LogInfo((object)(flag ? $"[Coin] Münzpunkt für '{((Object)c).name}' (Spieler {c.networkNumber}) vergeben ({when})" : ("[Coin] Münzpunkt für '" + ((Object)c).name + "' NICHT vergeben: Münzpunkte sind in den Regeln aus oder kein ScoreKeeper"))); } } } private static GameObject CreateVisual(Character c) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown GameObject val = new GameObject("LuckyWheelCoin"); SpriteRenderer val2 = val.AddComponent<SpriteRenderer>(); val2.sprite = WheelGraphics.CoinSprite; SpriteRenderer componentInChildren = ((Component)c).GetComponentInChildren<SpriteRenderer>(); if ((Object)(object)componentInChildren != (Object)null) { ((Renderer)val2).sortingLayerID = ((Renderer)componentInChildren).sortingLayerID; } ((Renderer)val2).sortingOrder = 600; return val; } private void Update() { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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) //IL_018a: Unknown result type (might be due to invalid IL or missing references) bool flag = LuckyWheelTrap.InPlay(); if (!flag) { LuckyWheelTrap.ResetRiskLevels(); } if (carried.Count == 0) { return; } done.Clear(); foreach (KeyValuePair<Character, Carried> item in carried) { Character key = item.Key; Carried value = item.Value; if ((Object)(object)key == (Object)null || !flag) { Plugin.LogVerbose("[Coin] Glücksrad-Münze verfällt (Runde vorbei)"); done.Add(key); continue; } if (key.Success) { Award(key, value.Count, "im Ziel"); done.Add(key); continue; } if (key.Dead || key.Dying) { Plugin.Log.LogInfo((object)$"[Coin] '{((Object)key).name}' ist gestorben, {value.Count} Glücksrad-Münze(n) verloren"); done.Add(key); continue; } Vector3 position = ((Component)key).transform.position; int count = value.Visuals.Count; for (int i = 0; i < count; i++) { if ((Object)(object)value.Visuals[i] != (Object)null) { float num = ((float)i - (float)(count - 1) / 2f) * 0.42f; float num2 = Mathf.Sin(Time.time * 4f + (float)i * 0.7f) * 0.08f; value.Visuals[i].transform.position = new Vector3(position.x + num, position.y + 1.5f + num2, position.z); } } } foreach (Character item2 in done) { if (!carried.TryGetValue(item2, out var value2)) { continue; } foreach (GameObject visual in value2.Visuals) { if ((Object)(object)visual != (Object)null) { Object.Destroy((Object)(object)visual); } } carried.Remove(item2); } } } internal static class WheelGraphics { internal const float WheelRadius = 0.9f; private const int Size = 128; private static readonly Color DeathColor = new Color(0.85f, 0.15f, 0.15f); private static readonly Color CoinColor = new Color(0.25f, 0.75f, 0.3f); private static readonly Color NeutralColorA = new Color(0.2f, 0.5f, 0.8f); private static readonly Color NeutralColorB = new Color(0.55f, 0.6f, 0.68f); private static readonly Color LineColor = new Color(0.1f, 0.1f, 0.1f); private static readonly Color Gold = new Color(1f, 0.82f, 0.2f); private static readonly Color GoldDark = new Color(0.8f, 0.55f, 0.1f); private static readonly Dictionary<int, Sprite> wheelSprites = new Dictionary<int, Sprite>(); private static Sprite pointerSprite; private static Sprite coinSprite; private static readonly HashSet<string> reported = new HashSet<string>(); private static readonly Dictionary<int, Sprite> blockSprites = new Dictionary<int, Sprite>(); private static Sprite pixelSprite; private static bool customBlockChecked; private static Texture2D customBlock; private static Rect customBlockBody = new Rect(0f, 0f, 1f, 1f); private static float customWheelX = float.NaN; private static readonly Dictionary<Sprite, float> rimFractions = new Dictionary<Sprite, float>(); private static string PluginDir => Path.GetDirectoryName(typeof(WheelGraphics).Assembly.Location) ?? "."; internal static Sprite PointerSprite { get { //IL_0032: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) if ((Object)(object)pointerSprite != (Object)null) { return pointerSprite; } Texture2D val = LoadCustom("pointer.png"); if ((Object)(object)val != (Object)null) { pointerSprite = FullSprite(val, new Vector2(0.5f, 0f), 0.4f, "LuckyWheelPointer"); return pointerSprite; } Texture2D val2 = NewTexture(32, 32); Color[] array = (Color[])(object)new Color[1024]; for (int i = 0; i < 32; i++) { float num = (float)i / 31f * 16f; for (int j = 0; j < 32; j++) { float num2 = Mathf.Abs((float)j - 15.5f); array[i * 32 + j] = ((num2 > num) ? Color.clear : ((num2 > num - 2.5f || i > 28) ? LineColor : Color.white)); } } val2.SetPixels(array); val2.Apply(); pointerSprite = Sprite.Create(val2, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0f), 80f); ((Object)pointerSprite).name = "LuckyWheelPointer"; return pointerSprite; } } internal static float WheelOffsetFraction { get { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!TryGetCustomBlock(out var _, out var body) || float.IsNaN(customWheelX)) { return 0f; } return (customWheelX - ((Rect)(ref body)).center.x) / ((Rect)(ref body)).width; } } internal static Sprite PixelSprite { get { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) if ((Object)(object)pixelSprite == (Object)null) { Texture2D obj = NewTexture(1, 1); obj.SetPixel(0, 0, Color.white); obj.Apply(); pixelSprite = Sprite.Create(obj, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0f), 1f); ((Object)pixelSprite).name = "LuckyWheelPixel"; } return pixelSprite; } } internal static Sprite CoinSprite { get { //IL_0032: 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_0120: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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) if ((Object)(object)coinSprite != (Object)null) { return coinSprite; } Texture2D val = LoadCustom("coin.png"); if ((Object)(object)val != (Object)null) { coinSprite = FullSprite(val, new Vector2(0.5f, 0.5f), 0.5f, "LuckyWheelCoin"); return coinSprite; } Texture2D val2 = NewTexture(48, 48); Color[] array = (Color[])(object)new Color[2304]; float num = 23.5f; for (int i = 0; i < 48; i++) { for (int j = 0; j < 48; j++) { float num2 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)); array[i * 48 + j] = ((num2 > 23f) ? Color.clear : ((num2 > 20f) ? LineColor : ((num2 > 13f) ? Gold : GoldDark))); } } val2.SetPixels(array); val2.Apply(); coinSprite = Sprite.Create(val2, new Rect(0f, 0f, 48f, 48f), new Vector2(0.5f, 0.5f), 96f); ((Object)coinSprite).name = "LuckyWheelCoin"; return coinSprite; } } internal static string FindFile(string file) { string text = Path.Combine(Path.Combine(PluginDir, "textures"), file); if (File.Exists(text)) { return text; } string text2 = Path.Combine(PluginDir, file); if (!File.Exists(text2)) { return null; } return text2; } private static Texture2D LoadCustom(string file) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown try { string text = FindFile(file); if (text == null) { if (reported.Add(file)) { Plugin.Log.LogWarning((object)("[Grafik] '" + file + "' nicht gefunden (weder in 'textures' noch neben der DLL), es wird die eingebaute Grafik benutzt")); } return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text))) { Plugin.Log.LogWarning((object)("[Grafik] '" + file + "' konnte nicht gelesen werden, es wird die eingebaute Grafik benutzt")); return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; if (reported.Add(file)) { Plugin.Log.LogInfo((object)$"[Grafik] Eigene Grafik geladen: {file} ({((Texture)val).width} x {((Texture)val).height})"); } return val; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Grafik] Fehler beim Laden von '" + file + "': " + ex.Message)); return null; } } private static Sprite FullSprite(Texture2D tex, Vector2 pivot, float unitsWide, string name) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Sprite obj = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), pivot, (float)((Texture)tex).width / unitsWide); ((Object)obj).name = name; return obj; } private static Texture2D NewTexture(int w, int h) { //IL_0004: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return new Texture2D(w, h, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; } internal static Sprite GetWheelSprite(int deathFields, int coinFields) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_01fe: 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_020a: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) int key = deathFields * 10 + coinFields; if (wheelSprites.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = LoadCustom($"wheel_{deathFields}_{coinFields}.png"); if ((Object)(object)val != (Object)null) { Sprite val2 = FullSprite(val, new Vector2(0.5f, 0.5f), 1.8f, "LuckyWheel_" + key); wheelSprites[key] = val2; return val2; } Texture2D val3 = NewTexture(128, 128); Color[] array = (Color[])(object)new Color[16384]; float num = 63.5f; float num2 = 63f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num3 = (float)j - num; float num4 = (float)i - num; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); Color val4; if (num5 > num2) { val4 = Color.clear; } else if (num5 > num2 - 4f || num5 < 6f || Mathf.Abs(num3) < 1.5f || Mathf.Abs(num4) < 1.5f) { val4 = LineColor; } else { float num6 = Mathf.Atan2(num4, num3) * 57.29578f; if (num6 < 0f) { num6 += 360f; } int num7 = Mathf.Min((int)(num6 / 90f), 3); if (num7 < deathFields) { val4 = DeathColor; } else if (num7 < deathFields + coinFields) { float num8 = ((float)num7 * 90f + 45f) * ((float)Math.PI / 180f); float num9 = Mathf.Cos(num8) * num2 * 0.55f; float num10 = Mathf.Sin(num8) * num2 * 0.55f; float num11 = Mathf.Sqrt((num3 - num9) * (num3 - num9) + (num4 - num10) * (num4 - num10)); val4 = ((num11 < 9f) ? Gold : ((num11 < 11.5f) ? GoldDark : CoinColor)); } else { val4 = ((num7 % 2 == 0) ? NeutralColorA : NeutralColorB); } } array[i * 128 + j] = val4; } } val3.SetPixels(array); val3.Apply(); Sprite val5 = Sprite.Create(val3, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 71.111115f); ((Object)val5).name = "LuckyWheel_" + key; wheelSprites[key] = val5; return val5; } internal static Sprite GetBlockSprite(float width, float height) { //IL_02ca: 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_0179: 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_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0200: 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_020f: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(Mathf.RoundToInt(width * 64f), 16, 512); int num2 = Mathf.Clamp(Mathf.RoundToInt(height * 64f), 16, 512); int key = num * 1000 + num2; if (blockSprit