using System; using System.Collections; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Newtonsoft.Json; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; 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("quasikyo")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+88856588778831b31dc3d36fe1b49c0fbe446e55")] [assembly: AssemblyProduct("ThunderRain")] [assembly: AssemblyTitle("ThunderRain")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/quasikyo/ror2-mods/tree/main/ThunderRain")] [assembly: AssemblyVersion("2.0.0.0")] namespace ThunderRain; internal static class ConfigManager { internal static ConfigEntry TimeSpanSeconds; internal static ConfigEntry ShockerSelection; internal static ConfigFile OptionsConfig { get; set; } internal static ConfigEntry PiShockUsername { get; set; } internal static ConfigEntry PiShockApiKey { get; set; } internal static ConfigEntry PiShockShockerIds { get; set; } internal static ConfigEntry VibrationsFromDealingDamage { get; set; } internal static ConfigEntry VibrationsFromReceivingDamage { get; set; } internal static ConfigEntry ShocksFromDealingDamage { get; set; } internal static ConfigEntry ShocksFromReceivingDamage { get; set; } internal static ConfigEntry VibrationsFromMinionsDealingDamage { get; set; } internal static ConfigEntry VibrationsFromMinionsReceivingDamage { get; set; } internal static ConfigEntry ShocksFromMinionsDealingDamage { get; set; } internal static ConfigEntry ShocksFromMinionsReceivingDamage { get; set; } internal static ConfigEntry ShockOnDeath { get; set; } internal static ConfigEntry BaseVibrationDurationSeconds { get; set; } internal static ConfigEntry BaseShockDurationSeconds { get; set; } internal static ConfigEntry DealingDamageBaseVibrationIntensity { get; set; } internal static ConfigEntry DealingDamageBaseShockIntensity { get; set; } internal static ConfigEntry ReceivingDamageBaseVibrationIntensity { get; set; } internal static ConfigEntry ReceivingDamageBaseShockIntensity { get; set; } internal static ConfigEntry MaximumVibrationIntensity { get; set; } internal static ConfigEntry MaximumShockIntensity { get; set; } internal static ConfigEntry MaximumVibrationDuration { get; set; } internal static ConfigEntry MaximumShockDuration { get; set; } internal static ConfigEntry ShockOnDeathIntensity { get; set; } internal static ConfigEntry ShockOnDeathDuration { get; set; } internal static ConfigEntry AllowExcessDamage { get; set; } static ConfigManager() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Expected O, but got Unknown //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Expected O, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Expected O, but got Unknown //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Expected O, but got Unknown //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Expected O, but got Unknown //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Expected O, but got Unknown //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Expected O, but got Unknown //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Expected O, but got Unknown //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Expected O, but got Unknown //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Expected O, but got Unknown //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Expected O, but got Unknown //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Expected O, but got Unknown //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Expected O, but got Unknown //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Expected O, but got Unknown //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Expected O, but got Unknown //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Expected O, but got Unknown //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Expected O, but got Unknown //IL_0514: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Expected O, but got Unknown //IL_0540: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Expected O, but got Unknown //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_055e: Expected O, but got Unknown //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_058a: Expected O, but got Unknown //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Expected O, but got Unknown //IL_05c2: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Expected O, but got Unknown //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Expected O, but got Unknown OptionsConfig = new ConfigFile(Paths.ConfigPath + "\\ThunderRain.cfg", true); ModSettingsManager.SetModDescription("Shocks PiShocks in response to in-game damage events."); PiShockUsername = OptionsConfig.Bind("PiShock Info", "PiShock Username", "", "Your PiShock username."); ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PiShockUsername)); PiShockApiKey = OptionsConfig.Bind("PiShock Info", "PiShock API Key", "", "Generated at https://pishock.com/#/account."); ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PiShockApiKey)); PiShockShockerIds = OptionsConfig.Bind("PiShock Info", "PiShock Shocker IDs", "", "ID of a shocker found in the shocker's info. Separate each ID with a comma. Refer to https://docs.pishock.com/pishock/pishock-v3-documentation.html#Shocker_Interface_0."); ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(PiShockShockerIds)); VibrationsFromDealingDamage = OptionsConfig.Bind("Activated By", "Vibrations from Dealing Damage", true, "Generate vibrations when dealing damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(VibrationsFromDealingDamage)); VibrationsFromReceivingDamage = OptionsConfig.Bind("Activated By", "Vibrations from Receiving Damage", true, "Generate vibrations when receiving damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(VibrationsFromReceivingDamage)); ShocksFromDealingDamage = OptionsConfig.Bind("Activated By", "Shocks from Dealing Damage", false, "Generate shocks when dealing damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShocksFromDealingDamage)); ShocksFromReceivingDamage = OptionsConfig.Bind("Activated By", "Shocks from Receiving Damage", false, "Generate shocks when receiving damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShocksFromReceivingDamage)); VibrationsFromMinionsDealingDamage = OptionsConfig.Bind("Activated By", "Vibrations from Minions Dealing Damage", false, "Generate vibrations when your minions (drones, turrets, etc.) deal damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(VibrationsFromMinionsDealingDamage)); VibrationsFromMinionsReceivingDamage = OptionsConfig.Bind("Activated By", "Vibrations from Minions Receiving Damage", false, "Generate vibrations when your minions (drones, turrets, etc.) receive damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(VibrationsFromMinionsReceivingDamage)); ShocksFromMinionsDealingDamage = OptionsConfig.Bind("Activated By", "Shocks from Minions Dealing Damage", false, "Generate shocks when your minions (drones, turrets, etc.) deal damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShocksFromMinionsDealingDamage)); ShocksFromMinionsReceivingDamage = OptionsConfig.Bind("Activated By", "Shocks from Minions Receiving Damage", false, "Generate shocks when your minions (drones, turrets, etc.) receive damage."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShocksFromMinionsReceivingDamage)); ShockOnDeath = OptionsConfig.Bind("Activated By", "Shock on Death", false, "Get shocked on death."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ShockOnDeath)); BaseVibrationDurationSeconds = OptionsConfig.Bind("Operation Values", "Base Vibration Duration in Seconds", 3, new ConfigDescription("The base vibration duration in seconds to add when damage is dealt or received. Multiplied by (damageDealt / maxHealthOfDamagedEntity).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 15), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(BaseVibrationDurationSeconds)); BaseShockDurationSeconds = OptionsConfig.Bind("Operation Values", "Base Shock Duration in Seconds", 1, new ConfigDescription("The base shock duration in seconds to add when damage is dealt or received. Multiplied by (damageDealt / maxHealthOfDamagedEntity).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 15), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(BaseShockDurationSeconds)); DealingDamageBaseVibrationIntensity = OptionsConfig.Bind("Operation Values", "Base Vibration Intensity on Damage Dealt", 50, new ConfigDescription("The base vibration intensity for vibrations generated by dealing damage. Multiplied by (damageDealt / maxHealthOfDamagedEntity).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(DealingDamageBaseVibrationIntensity)); DealingDamageBaseShockIntensity = OptionsConfig.Bind("Operation Values", "Base Shock Intensity on Damage Dealt", 1, new ConfigDescription("The base shock intensity for shocks generated by dealing damage. Multiplied by (damageDealt / maxHealthOfDamagedEntity).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(DealingDamageBaseShockIntensity)); ReceivingDamageBaseVibrationIntensity = OptionsConfig.Bind("Operation Values", "Base Vibration Intensity on Damage Received", 50, new ConfigDescription("The base vibration intensity for vibrations generated by receiving damage. Multiplied by (damageDealt / maxHealthOfDamagedEntity).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ReceivingDamageBaseVibrationIntensity)); ReceivingDamageBaseShockIntensity = OptionsConfig.Bind("Operation Values", "Base Shock Intensity on Damage Received", 1, new ConfigDescription("The base shock intensity for shocks generated by receiving damage. Multiplied by (damageDealt / maxHealthOfDamagedEntity).", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ReceivingDamageBaseShockIntensity)); MaximumVibrationIntensity = OptionsConfig.Bind("Operation Values", "Maximum Vibration Intensity", 100, new ConfigDescription("The maximum vibration intensity for a single operation.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaximumVibrationIntensity)); MaximumShockIntensity = OptionsConfig.Bind("Operation Values", "Maximum Shock Intensity", 100, new ConfigDescription("The maximum shock intensity for a single operation.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaximumShockIntensity)); MaximumVibrationDuration = OptionsConfig.Bind("Operation Values", "Maximum Vibration Duration Seconds", 15, new ConfigDescription("The maximum shock duration for a single operation in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 15), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaximumVibrationDuration)); MaximumShockDuration = OptionsConfig.Bind("Operation Values", "Maximum Shock Duration Seconds", 15, new ConfigDescription("The maximum shock duration for a single operation in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 15), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaximumShockDuration)); ShockOnDeathIntensity = OptionsConfig.Bind("Operation Values", "Shock on Death Intensity", 0, new ConfigDescription("Intensity of shock to receive on death independent of other calculations. Still subject to configured maximum.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ShockOnDeathIntensity)); ShockOnDeathDuration = OptionsConfig.Bind("Operation Values", "Shock on Death Duration Seconds", 0, new ConfigDescription("Duration of shock to receive on death independent of other calculations. Still subject to configured maximum.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 15), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ShockOnDeathDuration)); TimeSpanSeconds = OptionsConfig.Bind("Operation Behavior", "Time Span", 3, new ConfigDescription("Sums up values over this many seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100), Array.Empty())); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(TimeSpanSeconds)); ShockerSelection = OptionsConfig.Bind("Operation Behavior", "Shocker Selection", DeviceManager.ShockerSelection.Random, "Controls which shockers are selected when commands are sent."); ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)ShockerSelection)); AllowExcessDamage = OptionsConfig.Bind("Operation Behavior", "Allow For Excess Damage", false, "Allow for excess damage dealt over an entity's max combined health to affect operation intensity."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(AllowExcessDamage)); } } internal class DeviceManager { internal enum ShockerSelection { All, Random } private const string PiShockApiBaseUri = "https://api.pishock.com/"; private static readonly HttpClient HttpClient = new HttpClient { BaseAddress = new Uri("https://api.pishock.com/") }; internal string DisplayName { get; private set; } private PiShockShocker[] Shockers { get; set; } public DeviceManager(string displayName) { DisplayName = displayName; UpdateShockerList(null, null); ConfigManager.PiShockShockerIds.SettingChanged += UpdateShockerList; } private void UpdateShockerList(object _, EventArgs __) { Log.Info("Parsing \"" + ConfigManager.PiShockShockerIds.Value + "\" for shocker IDs"); Shockers = ConfigManager.PiShockShockerIds.Value.Split(',').Select(delegate(string id, int index) { Log.Info($"Shocker ID #{index + 1}: {id}"); return new PiShockShocker(id.Trim()); }).ToArray(); Log.Info($"Amount of shockers: {Shockers.Length}"); } private PiShockShocker GetRandomShocker() { return Shockers[new Random().Next(0, Shockers.Length)]; } internal void ProcessValuePool(ValuePool pool) { if (!pool.VibrationValues.IsNill()) { Operate(PiShockOperation.Vibrate, pool.VibrationValues); } if (!pool.ShockValues.IsNill()) { Operate(PiShockOperation.Shock, pool.ShockValues); } } private void Operate(PiShockOperation operation, PiShockValues values) { switch (ConfigManager.ShockerSelection.Value) { case ShockerSelection.All: { PiShockShocker[] shockers = Shockers; foreach (PiShockShocker shocker in shockers) { SendOperation(operation, values, shocker); } break; } case ShockerSelection.Random: SendOperation(operation, values, GetRandomShocker()); break; } } private async void SendOperation(PiShockOperation operation, PiShockValues values, PiShockShocker shocker) { string text = $"[{operation}/{shocker.ShockerId}]"; Log.Info($"{text} Sending {operation} to {shocker.ShockerId} with {values}"); string content = JsonConvert.SerializeObject((object)new PiShockRequest { AgentName = DisplayName, DurationMilliseconds = (int)values.Duration.TotalMilliseconds, Intensity = (int)values.Intensity, IntensityAsPercentage = false, Operation = (int)operation }); HttpRequestMessage request = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri("/Shockers/" + shocker.ShockerId, UriKind.Relative), Headers = { { "X-PiShock-Api-Key", ConfigManager.PiShockApiKey.Value } }, Content = new StringContent(content, Encoding.UTF8, "application/json") }; HandleOperationResponse(await HttpClient.SendAsync(request), operation, shocker); } private void HandleOperationResponse(HttpResponseMessage response, PiShockOperation operation, PiShockShocker shocker) { string text = $"[{operation}/{shocker.ShockerId}]"; if (!response.IsSuccessStatusCode) { string text2; switch (response.StatusCode) { case HttpStatusCode.Unauthorized: case HttpStatusCode.Forbidden: text2 = "Request could not be authorized. Please ensure your username, API key, and shocker ID(s) are correct."; break; case HttpStatusCode.NotFound: text2 = "Shocker ID of " + shocker.ShockerId + " could not be found."; break; case HttpStatusCode.MethodNotAllowed: text2 = $"{operation} is not enabled for shocker {shocker.ShockerId}."; break; case HttpStatusCode.NotAcceptable: text2 = "Shocker " + shocker.ShockerId + " is not flashed to V3. Please consult https://docs.pishock.com/pishock/pishock-v3-documentation.html."; break; default: text2 = $"Shocker ${shocker.ShockerId} failed to ${operation}: error code {response.StatusCode}"; break; } Log.Error(text + " " + text2); } } } internal static class Log { private static ManualLogSource Logger { get; set; } internal static void Init(ManualLogSource logger) { Logger = logger; } [Conditional("DEBUG")] internal static void Debug(object data) { Logger.LogDebug(data); } internal static void Info(object data) { Logger.LogInfo(data); } internal static void Message(object data) { Logger.LogMessage(data); } internal static void Warning(object data) { Logger.LogWarning(data); } internal static void Error(object data) { Logger.LogError(data); } internal static void Fatal(object data) { Logger.LogFatal(data); } } internal enum PiShockOperation { Shock, Vibrate, Beep } internal class PiShockRequest { [JsonProperty("AgentName")] [Obsolete("This field is being deprecated by the PiShock API and will be replaced by the name of the API key")] internal string AgentName { get; set; } [JsonProperty("Duration")] internal int DurationMilliseconds { get; set; } [JsonProperty("Intensity")] internal int Intensity { get; set; } [JsonProperty("IntensityAsPercentage")] internal bool IntensityAsPercentage { get; set; } [JsonProperty("Operation")] internal int Operation { get; set; } } internal class PiShockShocker { internal string ShockerId { get; set; } internal PiShockShocker(string shockerId) { ShockerId = shockerId; } } internal class PiShockValues { internal const int MaxApiDurationSeconds = 15; internal const int MaxApiIntensity = 100; private TimeSpan _duration = TimeSpan.Zero; private float _intensity; private int MaxIntensity { get; set; } private TimeSpan MaxDuration { get; set; } internal TimeSpan Duration { get { return _duration; } set { float num = Mathf.Clamp((float)value.TotalSeconds, 0f, (float)MaxDuration.TotalSeconds); _duration = TimeSpan.FromSeconds(num); } } internal float Intensity { get { return _intensity; } set { _intensity = Mathf.Clamp(value, 0f, (float)MaxIntensity); } } internal PiShockValues(int maxIntensity, int maxDurationSeconds) { MaxIntensity = maxIntensity; MaxDuration = TimeSpan.FromSeconds(maxDurationSeconds); } internal PiShockValues() : this(100, 15) { } internal bool IsNill() { bool num = Duration.TotalSeconds < 1.0; bool flag = Intensity < 1f; return num || flag; } public override string ToString() { return $"PiShockValues(Intensity={Intensity}, Duration={Duration.TotalSeconds}s)"; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("quasikyo.ThunderRain", "ThunderRain", "2.0.0")] public class ThunderRain : BaseUnityPlugin { private static ValuePool Buffer { get; set; } private static DeviceManager DeviceManager { get; set; } public void Awake() { Log.Init(((BaseUnityPlugin)this).Logger); Log.Info("Performing setup for ThunderRain"); Buffer = new ValuePool(); DeviceManager = new DeviceManager("ThunderRain"); GlobalEventManager.onClientDamageNotified += OperateDevicesOnDamage; GlobalEventManager.onCharacterDeathGlobal += OperateDevicesOnDeath; } private void OperateDevicesOnDeath(DamageReport report) { if (ConfigManager.ShockOnDeath.Value && !((Object)(object)LocalUserManager.GetFirstLocalUser().cachedMaster.GetBody() != (Object)(object)report.victimBody)) { ValuePool valuePool = new ValuePool(); valuePool.ShockValues.Intensity = ConfigManager.ShockOnDeathIntensity.Value; valuePool.ShockValues.Duration = TimeSpan.FromSeconds(ConfigManager.ShockOnDeathDuration.Value); DeviceManager.ProcessValuePool(valuePool); } } private IEnumerator ReadBuffer() { Buffer.SetActive(); yield return (object)new WaitForSeconds((float)ConfigManager.TimeSpanSeconds.Value); DeviceManager.ProcessValuePool(Buffer); Buffer.Reset(); } private void OperateDevicesOnDamage(DamageDealtMessage damageMessage) { CharacterMaster cachedMaster = LocalUserManager.GetFirstLocalUser().cachedMaster; CharacterBody body = cachedMaster.GetBody(); GameObject victim = damageMessage.victim; CharacterBody val = ((victim != null) ? victim.GetComponent() : null); GameObject attacker = damageMessage.attacker; CharacterBody val2 = ((attacker != null) ? attacker.GetComponent() : null); if (!((Object)(object)val == (Object)null)) { if (Buffer.Status == ValuePool.PoolStatus.Empty) { ((MonoBehaviour)this).StartCoroutine(ReadBuffer()); } float fullCombinedHealth = val.healthComponent.fullCombinedHealth; float num = damageMessage.damage / fullCombinedHealth; if (!ConfigManager.AllowExcessDamage.Value) { num = Math.Min(num, 1f); } bool flag = (Object)(object)body == (Object)(object)val2; bool num2 = (Object)(object)body == (Object)(object)val; object obj; if (val2 == null) { obj = null; } else { CharacterMaster master = val2.master; obj = ((master != null) ? master.minionOwnership.ownerMaster : null); } bool flag2 = (Object)obj == (Object)(object)cachedMaster; CharacterMaster master2 = val.master; bool flag3 = (Object)(object)((master2 != null) ? master2.minionOwnership.ownerMaster : null) == (Object)(object)cachedMaster; if ((flag && ConfigManager.VibrationsFromDealingDamage.Value) || (flag2 && ConfigManager.VibrationsFromMinionsDealingDamage.Value)) { Buffer.VibrationValues.Duration += TimeSpan.FromSeconds((float)ConfigManager.BaseVibrationDurationSeconds.Value * num); Buffer.VibrationValues.Intensity += (float)ConfigManager.DealingDamageBaseVibrationIntensity.Value * num; } if ((flag && ConfigManager.ShocksFromDealingDamage.Value) || (flag2 && ConfigManager.ShocksFromMinionsDealingDamage.Value)) { Buffer.ShockValues.Duration += TimeSpan.FromSeconds((float)ConfigManager.BaseShockDurationSeconds.Value * num); Buffer.ShockValues.Intensity += (float)ConfigManager.DealingDamageBaseShockIntensity.Value * num; } if ((num2 && ConfigManager.VibrationsFromReceivingDamage.Value) || (flag3 && ConfigManager.VibrationsFromMinionsReceivingDamage.Value)) { Buffer.VibrationValues.Duration += TimeSpan.FromSeconds((float)ConfigManager.BaseVibrationDurationSeconds.Value * num); Buffer.VibrationValues.Intensity += (float)ConfigManager.ReceivingDamageBaseVibrationIntensity.Value * num; } if ((num2 && ConfigManager.ShocksFromReceivingDamage.Value) || (flag3 && ConfigManager.ShocksFromMinionsReceivingDamage.Value)) { Buffer.ShockValues.Duration += TimeSpan.FromSeconds((float)ConfigManager.BaseShockDurationSeconds.Value * num); Buffer.ShockValues.Intensity += (float)ConfigManager.ReceivingDamageBaseShockIntensity.Value * num; } } } } internal class ValuePool { internal enum PoolStatus { Empty, Active } internal PoolStatus Status { get; private set; } internal PiShockValues VibrationValues { get; set; } internal PiShockValues ShockValues { get; set; } internal ValuePool() { Reset(); ConfigManager.MaximumShockDuration.SettingChanged += ResetOnSettingChange; ConfigManager.MaximumShockIntensity.SettingChanged += ResetOnSettingChange; ConfigManager.MaximumVibrationDuration.SettingChanged += ResetOnSettingChange; ConfigManager.MaximumVibrationIntensity.SettingChanged += ResetOnSettingChange; } internal void SetActive() { Status = PoolStatus.Active; } private void ResetOnSettingChange(object sender, EventArgs e) { Reset(); } internal void Reset() { Status = PoolStatus.Empty; VibrationValues = new PiShockValues(ConfigManager.MaximumVibrationIntensity.Value, ConfigManager.MaximumVibrationDuration.Value); ShockValues = new PiShockValues(ConfigManager.MaximumShockIntensity.Value, ConfigManager.MaximumShockDuration.Value); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "quasikyo.ThunderRain"; public const string PLUGIN_NAME = "ThunderRain"; public const string PLUGIN_VERSION = "2.0.0"; }