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<IGameModeHandler, IEnumerator>)OnRoundStart);
GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)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<Player, float> _tickTimers = new Dictionary<Player, float>();
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>();
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>();
_audioSource.loop = true;
_audioSource.playOnAwake = false;
_audioSource.spatialBlend = 0f;
_tickAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
_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<AudioClip> 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<LineRenderer>();
_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<PhotonView>();
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<HealthHandler>();
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);
}
}
}
}