using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using ExitGames.Client.Photon; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnboundLib; using UnboundLib.GameModes; using UnboundLib.Networking; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShrinkingZoneMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ShrinkingZoneMod")] [assembly: AssemblyTitle("ShrinkingZoneMod")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ShrinkingZoneMod { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("yourname.rounds.shrinkingzone", "Shrinking Zone", "1.0.1")] public class ShrinkingZonePlugin : BaseUnityPlugin { public const string ModId = "yourname.rounds.shrinkingzone"; public const string ModName = "Shrinking Zone"; public const string Version = "1.0.1"; public static float StartRadius = 50f; public static float FinalRadius = 8f; public static float ShrinkStartDelay = 5f; public static float ShrinkDuration = 25f; public static float DamagePercentPerSecond = 0.1f; public static float DamageTickInterval = 0.5f; public static float DamageGracePeriod = 10f; private void Awake() { GameModeManager.AddHook("PointStart", (Func)OnRoundStart); GameModeManager.AddHook("PointEnd", (Func)OnRoundEnd); } private IEnumerator OnRoundStart(IGameModeHandler gm) { if ((Object)(object)PlayerManager.instance != (Object)null) { foreach (Player p in PlayerManager.instance.players) { if ((Object)(object)p != (Object)null) { Debug.LogWarning($"[ShrinkingZoneMod] Player at spawn: {((Component)p).transform.position}"); } } } ZoneController.SpawnZone(Vector2.zero, StartRadius, FinalRadius, ShrinkStartDelay, ShrinkDuration, DamagePercentPerSecond, DamageTickInterval, DamageGracePeriod); yield break; } private IEnumerator OnRoundEnd(IGameModeHandler gm) { ZoneController.DespawnZone(); yield break; } } public class ZoneController : MonoBehaviour { private static ZoneController _active; public Vector2 Center; public float StartRadius; public float FinalRadius; public float ShrinkDelay; public float ShrinkDuration; public float DamagePercentPerSecond; public float TickInterval; public float DamageGracePeriod; private float _currentRadius; private float _timer; private LineRenderer _ring; private readonly Dictionary _tickTimers = new Dictionary(); private const float SyncInterval = 0.2f; private float _syncTimer; private const string ShrinkSoundFileName = "ring_collapse.wav"; private const string DamageTickSoundFileName = "damage_tick.wav"; private static AudioClip _shrinkSoundClip; private static AudioClip _damageTickSoundClip; private static bool _shrinkSoundLoadAttempted; private static bool _damageTickSoundLoadAttempted; private AudioSource _audioSource; private AudioSource _tickAudioSource; public static void SpawnZone(Vector2 center, float startRadius, float finalRadius, float shrinkDelay, float shrinkDuration, float damagePercentPerSecond, float tickInterval, float damageGracePeriod = 0f) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) DespawnZone(); GameObject val = new GameObject("ShrinkingZone"); ZoneController zoneController = val.AddComponent(); zoneController.Center = center; zoneController.StartRadius = startRadius; zoneController.FinalRadius = finalRadius; zoneController.ShrinkDelay = shrinkDelay; zoneController.ShrinkDuration = shrinkDuration; zoneController.DamagePercentPerSecond = damagePercentPerSecond; zoneController.TickInterval = tickInterval; zoneController.DamageGracePeriod = damageGracePeriod; _active = zoneController; } public static void DespawnZone() { if ((Object)(object)_active != (Object)null) { Object.Destroy((Object)(object)((Component)_active).gameObject); _active = null; } } private void Awake() { _currentRadius = StartRadius; _timer = 0f; _syncTimer = 0f; SetupRingVisual(); SetupAudio(); } private void SetupAudio() { _audioSource = ((Component)this).gameObject.AddComponent(); _audioSource.loop = true; _audioSource.playOnAwake = false; _audioSource.spatialBlend = 0f; _tickAudioSource = ((Component)this).gameObject.AddComponent(); _tickAudioSource.loop = false; _tickAudioSource.playOnAwake = false; _tickAudioSource.spatialBlend = 0f; if ((Object)(object)_shrinkSoundClip == (Object)null && !_shrinkSoundLoadAttempted) { _shrinkSoundLoadAttempted = true; ((MonoBehaviour)this).StartCoroutine(LoadAudioClip("ring_collapse.wav", delegate(AudioClip clip) { _shrinkSoundClip = clip; })); } if ((Object)(object)_damageTickSoundClip == (Object)null && !_damageTickSoundLoadAttempted) { _damageTickSoundLoadAttempted = true; ((MonoBehaviour)this).StartCoroutine(LoadAudioClip("damage_tick.wav", delegate(AudioClip clip) { _damageTickSoundClip = clip; })); } } private IEnumerator LoadAudioClip(string fileName, Action onLoaded) { string pluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string filePath = Path.Combine(pluginDir ?? "", fileName); if (!File.Exists(filePath)) { Debug.LogWarning("[ShrinkingZoneMod] Sound file not found at: " + filePath + " -- this sound will be silent. Make sure " + fileName + " is placed next to ShrinkingZoneMod.dll."); yield break; } AudioType audioType = GetAudioTypeFromExtension(filePath); string uri = "file://" + filePath.Replace("\\", "/"); UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(uri, audioType); try { yield return req.SendWebRequest(); if (req.isNetworkError || req.isHttpError) { Debug.LogWarning("[ShrinkingZoneMod] Failed to load sound file " + fileName + ": " + req.error); yield break; } onLoaded(DownloadHandlerAudioClip.GetContent(req)); Debug.LogWarning("[ShrinkingZoneMod] Loaded sound: " + fileName); } finally { ((IDisposable)req)?.Dispose(); } } private static AudioType GetAudioTypeFromExtension(string path) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_004a: Unknown result type (might be due to invalid IL or missing references) return (AudioType)(Path.GetExtension(path).ToLowerInvariant() switch { ".wav" => 20, ".ogg" => 14, ".mp3" => 13, _ => 0, }); } private void SetupRingVisual() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) _ring = ((Component)this).gameObject.AddComponent(); _ring.loop = true; _ring.positionCount = 64; _ring.widthMultiplier = 0.6f; _ring.useWorldSpace = true; ((Renderer)_ring).material = new Material(Shader.Find("Sprites/Default")); _ring.startColor = new Color(1f, 0.2f, 0.2f, 0.8f); _ring.endColor = new Color(1f, 0.2f, 0.2f, 0.8f); DrawRing(); } private void DrawRing() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); for (int i = 0; i < _ring.positionCount; i++) { float num = (float)i / (float)_ring.positionCount * MathF.PI * 2f; ((Vector3)(ref val))..ctor(Center.x + Mathf.Cos(num) * _currentRadius, Center.y + Mathf.Sin(num) * _currentRadius, 0f); _ring.SetPosition(i, val); } } private void UpdateShrinkSound() { if ((Object)(object)_audioSource == (Object)null || (Object)(object)_shrinkSoundClip == (Object)null) { return; } if (_timer >= ShrinkDelay && _timer < ShrinkDelay + ShrinkDuration) { if ((Object)(object)_audioSource.clip != (Object)(object)_shrinkSoundClip) { _audioSource.clip = _shrinkSoundClip; } if (!_audioSource.isPlaying) { _audioSource.Play(); } } else if (_audioSource.isPlaying) { _audioSource.Stop(); } } private void Update() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.IsMasterClient) { _timer += Time.deltaTime; if (_timer >= ShrinkDelay) { float num = Mathf.Clamp01((_timer - ShrinkDelay) / ShrinkDuration); _currentRadius = Mathf.Lerp(StartRadius, FinalRadius, num); } _syncTimer += Time.deltaTime; if (_syncTimer >= 0.2f) { _syncTimer = 0f; NetworkingManager.RPC(typeof(ZoneController), "RPCA_SyncZoneState", RaiseEventOptions.Default, SendOptions.SendReliable, new object[4] { Center.x, Center.y, _currentRadius, _timer }); } } DrawRing(); UpdateShrinkSound(); if ((Object)(object)PlayerManager.instance == (Object)null || _timer < DamageGracePeriod) { return; } foreach (Player player in PlayerManager.instance.players) { if ((Object)(object)player == (Object)null) { continue; } Vector2 val = Vector2.op_Implicit(((Component)player).transform.position); if (!(Vector2.Distance(val, Center) > _currentRadius)) { _tickTimers.Remove(player); continue; } Debug.LogWarning($"[ShrinkingZoneMod] {((Object)player).name} is outside zone (dist={Vector2.Distance(val, Center):F1}, radius={_currentRadius:F1})."); if (!_tickTimers.ContainsKey(player)) { _tickTimers[player] = 0f; } _tickTimers[player] += Time.deltaTime; if (_tickTimers[player] >= TickInterval) { _tickTimers[player] -= TickInterval; ApplyZoneDamage(player, DamagePercentPerSecond * TickInterval); } } } private void ApplyZoneDamage(Player player, float percentOfMaxHealth) { //IL_00e4: 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_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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) PhotonView component = ((Component)player).GetComponent(); if ((Object)(object)component != (Object)null && !component.IsMine) { Debug.LogWarning("[ShrinkingZoneMod] Skipping damage for " + ((Object)player).name + ": not locally owned (view.IsMine == false)."); return; } float maxHealth = player.data.maxHealth; if (maxHealth <= 0f) { Debug.LogWarning($"[ShrinkingZoneMod] Skipping damage for {((Object)player).name}: maxHealth <= 0 ({maxHealth})."); return; } float num = maxHealth * percentOfMaxHealth; HealthHandler componentInChildren = ((Component)player).GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { Debug.LogWarning("[ShrinkingZoneMod] No HealthHandler found on " + ((Object)player).name + " or its children -- damage cannot be applied."); return; } Debug.LogWarning($"[ShrinkingZoneMod] Applying {num:F1} zone damage to {((Object)player).name} (maxHealth={maxHealth})."); Vector2 val = Vector2.op_Implicit(((Component)player).transform.position) - Center; Vector2 val2 = ((Vector2)(ref val)).normalized; if (val2 == Vector2.zero) { val2 = Vector2.up; } Vector2 val3 = val2 * num; ((Damagable)componentInChildren).CallTakeDamage(val3, Vector2.op_Implicit(((Component)player).transform.position), (GameObject)null, (Player)null, true); if ((Object)(object)_tickAudioSource != (Object)null && (Object)(object)_damageTickSoundClip != (Object)null) { Debug.LogWarning($"[ShrinkingZoneMod] Playing damage tick sound. audioSource.enabled={((Behaviour)_tickAudioSource).enabled}, gameObject.activeInHierarchy={((Component)this).gameObject.activeInHierarchy}, clip.length={_damageTickSoundClip.length:F2}, clip.loadState={_damageTickSoundClip.loadState}."); _tickAudioSource.PlayOneShot(_damageTickSoundClip); } else { Debug.LogWarning($"[ShrinkingZoneMod] Damage tick sound NOT played -- audioSource null? {(Object)(object)_tickAudioSource == (Object)null}, clip null? {(Object)(object)_damageTickSoundClip == (Object)null}."); } } [UnboundRPC] private static void RPCA_SyncZoneState(float centerX, float centerY, float radius, float timer) { //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) if (!((Object)(object)_active == (Object)null)) { _active.Center = new Vector2(centerX, centerY); _active._currentRadius = radius; _active._timer = timer; } } private void OnDestroy() { if ((Object)(object)_ring != (Object)null) { Object.Destroy((Object)(object)_ring); } } } }