Decompiled source of RainDance v1.0.1

plugins/RainDance.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RainDance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a939bded0cc222379ed02c4c64f25e2b4e324322")]
[assembly: AssemblyProduct("RainDance")]
[assembly: AssemblyTitle("RainDance")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RainDance;

[BepInPlugin("raindance", "RainDance", "1.0.1")]
public class RainDancePlugin : BaseUnityPlugin
{
	private enum WeatherStage
	{
		None,
		Rain,
		Storm
	}

	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	private static class Patch_ZRoutedRpc_Ctor
	{
		private static void Postfix(ZRoutedRpc __instance)
		{
			__instance.Register<string>("RainDance_SetWeather", (Action<long, string>)delegate(long sender, string env)
			{
				Log.LogInfo((object)("RainDance_SetWeather received: \"" + env + "\""));
				if ((Object)(object)EnvMan.instance != (Object)null)
				{
					EnvMan.instance.SetForceEnvironment(env);
				}
			});
		}
	}

	public const string PluginGUID = "raindance";

	public const string PluginName = "RainDance";

	public const string PluginVersion = "1.0.1";

	internal static ManualLogSource Log;

	private Harmony _harmony;

	private ConfigEntry<float> _rainSeconds;

	private ConfigEntry<float> _stormSeconds;

	private ConfigEntry<float> _weatherDurationSeconds;

	private ConfigEntry<string> _msgRain;

	private ConfigEntry<string> _msgStorm;

	private ConfigEntry<string> _msgCleared;

	private WeatherStage _stage;

	private float _weatherTimer;

	private readonly Dictionary<long, float> _playerTimers = new Dictionary<long, float>();

	private readonly List<(float, string)> _pendingMessages = new List<(float, string)>();

	private const float EnvTransitionDelay = 2f;

	private const float WindTransitionDelay = 5f;

	private void Awake()
	{
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		_rainSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Durations", "RainDanceSeconds", 10f, "Seconds of axe-dancing required to summon Rain.");
		_stormSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Durations", "StormDanceSeconds", 10f, "Additional seconds of axe-dancing (after Rain starts) to escalate to ThunderStorm.");
		_weatherDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Durations", "WeatherDurationSeconds", 60f, "How long (seconds) the summoned weather lasts before clearing. Set to 0 for permanent.");
		_msgRain = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "RainMessage", "An axe-dancer has pleased the rain spirits!", "Broadcast message when Rain is summoned.");
		_msgStorm = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "StormMessage", "The spirits are FURIOUS — a storm descends!", "Broadcast message when ThunderStorm is unleashed.");
		_msgCleared = ((BaseUnityPlugin)this).Config.Bind<string>("Messages", "ClearedMessage", "The storm has passed.", "Broadcast message when the weather returns to normal.");
		_harmony = new Harmony("raindance");
		_harmony.PatchAll();
		Log.LogInfo((object)"Rain Dance mod loaded.");
	}

	private void Update()
	{
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
		{
			return;
		}
		for (int num = _pendingMessages.Count - 1; num >= 0; num--)
		{
			(float, string) tuple = _pendingMessages[num];
			float item = tuple.Item1;
			string item2 = tuple.Item2;
			item -= Time.deltaTime;
			if (item <= 0f)
			{
				SendServerBroadcast(item2);
				_pendingMessages.RemoveAt(num);
			}
			else
			{
				_pendingMessages[num] = (item, item2);
			}
		}
		if (_stage != 0 && _weatherDurationSeconds.Value > 0f)
		{
			_weatherTimer -= Time.deltaTime;
			if (_weatherTimer <= 0f)
			{
				ClearWeather();
			}
		}
		foreach (ZNetPeer peer in ZNet.instance.GetPeers())
		{
			long uid = peer.m_uid;
			ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID);
			if (zDO == null)
			{
				continue;
			}
			bool flag = IsPlayerDancing(zDO);
			bool flag2 = IsPlayerHoldingAxe(zDO);
			if (flag && flag2)
			{
				if (!_playerTimers.ContainsKey(uid))
				{
					_playerTimers[uid] = 0f;
					Log.LogInfo((object)(peer.m_playerName + " started axe-dancing — timer started."));
				}
				_playerTimers[uid] += Time.deltaTime;
				float num2 = _playerTimers[uid];
				if (_stage == WeatherStage.None && num2 >= _rainSeconds.Value)
				{
					SetWeather(WeatherStage.Rain);
				}
				else if (_stage == WeatherStage.Rain && num2 >= _rainSeconds.Value + _stormSeconds.Value)
				{
					SetWeather(WeatherStage.Storm);
				}
			}
			else if (_playerTimers.ContainsKey(uid) && _playerTimers[uid] > 0f)
			{
				Log.LogInfo((object)("Peer " + peer.m_playerName + " stopped axe-dancing — timer reset."));
				_playerTimers[uid] = 0f;
			}
		}
		HashSet<long> hashSet = new HashSet<long>();
		foreach (ZNetPeer peer2 in ZNet.instance.GetPeers())
		{
			hashSet.Add(peer2.m_uid);
		}
		List<long> list = new List<long>();
		foreach (long key in _playerTimers.Keys)
		{
			if (!hashSet.Contains(key))
			{
				list.Add(key);
			}
		}
		foreach (long item3 in list)
		{
			_playerTimers.Remove(item3);
		}
	}

	private static bool IsPlayerDancing(ZDO zdo)
	{
		return zdo.GetString(ZDOVars.s_emote, "") == "dance";
	}

	private static bool IsPlayerHoldingAxe(ZDO zdo)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Invalid comparison between Unknown and I4
		int @int = zdo.GetInt(ZDOVars.s_rightItem, 0);
		if (@int == 0)
		{
			return false;
		}
		ZNetScene instance = ZNetScene.instance;
		GameObject val = ((instance != null) ? instance.GetPrefab(@int) : null);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		ItemDrop component = val.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			return false;
		}
		return (int)component.m_itemData.m_shared.m_skillType == 7;
	}

	private void SetWeather(WeatherStage stage)
	{
		_stage = stage;
		_weatherTimer = _weatherDurationSeconds.Value;
		string env;
		string value;
		if (stage == WeatherStage.Rain)
		{
			env = "Rain";
			value = _msgRain.Value;
			Log.LogInfo((object)"Stage 1 — Rain summoned.");
		}
		else
		{
			env = "ThunderStorm";
			value = _msgStorm.Value;
			Log.LogInfo((object)"Stage 2 — ThunderStorm unleashed!");
		}
		BroadcastWeather(env);
		float item = ((stage == WeatherStage.Rain) ? 2f : 5f);
		_pendingMessages.Add((item, value));
	}

	private void ClearWeather()
	{
		_stage = WeatherStage.None;
		_weatherTimer = 0f;
		_playerTimers.Clear();
		_pendingMessages.Clear();
		BroadcastWeather(string.Empty);
		_pendingMessages.Add((2f, _msgCleared.Value));
		Log.LogInfo((object)"Weather cleared — skies return to normal.");
	}

	private static void BroadcastWeather(string env)
	{
		if (ZRoutedRpc.instance != null)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RainDance_SetWeather", new object[1] { env });
			Log.LogInfo((object)("Broadcast RainDance_SetWeather: \"" + env + "\""));
		}
	}

	private static void SendServerBroadcast(string message)
	{
		if (!string.IsNullOrWhiteSpace(message) && ZRoutedRpc.instance != null)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ShowMessage", new object[2] { 2, message });
		}
	}

	private void OnDestroy()
	{
		ClearWeather();
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}
}