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 Photon.Pun;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("RandomDynamite")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: AssemblyInformationalVersion("1.7.0")]
[assembly: AssemblyProduct("RandomDynamite")]
[assembly: AssemblyTitle("RandomDynamite")]
[assembly: AssemblyVersion("1.7.0.0")]
namespace RandomDynamite;
public enum ExplosionDetail
{
Minimal,
Particles,
Full
}
[BepInPlugin("liam.RandomDynamite", "Random Dynamite", "1.7.0")]
public class Plugin : BaseUnityPlugin
{
private struct PendingSpawn
{
public float Time;
public Vector3 Position;
}
[HarmonyPatch(typeof(Dynamite), "EnableFlareVisuals")]
internal static class DynamiteFlareVisualsPatch
{
private static bool Prefix(Dynamite __instance)
{
Plugin instance = Instance;
if ((Object)(object)instance == (Object)null || !instance.SuppressSmoke)
{
return true;
}
return !instance.IsModDynamite(__instance);
}
}
[HarmonyPatch(typeof(Dynamite), "Update")]
internal static class DynamiteUpdatePatch
{
private static void Postfix(Dynamite __instance)
{
Plugin instance = Instance;
if (!((Object)(object)instance == (Object)null) && instance.SuppressSparks && instance.IsModDynamite(__instance))
{
if ((Object)(object)__instance.sparks != (Object)null)
{
((Component)__instance.sparks).gameObject.SetActive(false);
}
if ((Object)(object)__instance.sparksPhotosensitive != (Object)null)
{
((Component)__instance.sparksPhotosensitive).gameObject.SetActive(false);
}
}
}
}
public const string Guid = "liam.RandomDynamite";
public const string Name = "Random Dynamite";
public const string Version = "1.7.0";
private const string FallbackDynamitePrefab = "Dynamite";
internal static ManualLogSource Log;
public static Plugin Instance;
private ConfigEntry<bool> _enabledOnStart;
private ConfigEntry<KeyCode> _toggleKey;
private ConfigEntry<KeyCode> _manualBurstKey;
private ConfigEntry<float> _intervalMin;
private ConfigEntry<float> _intervalMax;
private ConfigEntry<int> _countMin;
private ConfigEntry<int> _countMax;
private ConfigEntry<float> _heightMin;
private ConfigEntry<float> _heightMax;
private ConfigEntry<float> _spreadRadius;
private ConfigEntry<float> _burstSpreadTime;
private ConfigEntry<bool> _spawnOnEnable;
private ConfigEntry<bool> _includeLocalPlayer;
private ConfigEntry<bool> _onlyAlive;
private ConfigEntry<bool> _lightFuses;
private ConfigEntry<bool> _verbose;
private ConfigEntry<bool> _suppressSmoke;
private ConfigEntry<bool> _suppressSparks;
private ConfigEntry<ExplosionDetail> _explosionDetail;
private ConfigEntry<bool> _randomiseFuse;
private ConfigEntry<float> _fuseJitterMin;
private ConfigEntry<float> _fuseJitterMax;
private ConfigEntry<int> _maxLiveDynamite;
private ConfigEntry<bool> _messagesEnabled;
private ConfigEntry<bool> _useGameNotifications;
private ConfigEntry<float> _messageDuration;
private ConfigEntry<bool> _persistentIndicator;
private bool _active;
private float _nextSpawnTime = float.MaxValue;
private bool _legacyInputAvailable = true;
private string _dynamitePrefabName;
private bool _loggedInputDiagnostics;
private bool _wasInRoom;
private readonly HashSet<Dynamite> _modDynamite = new HashSet<Dynamite>();
private readonly List<Dynamite> _staleDynamite = new List<Dynamite>();
private float _nextCleanupTime;
private bool _loggedExplosionPrefab;
private readonly Queue<PendingSpawn> _pendingSpawns = new Queue<PendingSpawn>();
private static readonly List<Character> Targets = new List<Character>();
private string _toastText;
private float _toastUntil;
private GUIStyle _toastStyle;
private GUIStyle _indicatorStyle;
private Texture2D _toastBackground;
private UI_Notifications _notifications;
private bool _nativeNotificationsUnavailable;
internal bool SuppressSmoke => _suppressSmoke.Value;
internal bool SuppressSparks => _suppressSparks.Value;
private ExplosionDetail CurrentExplosionDetail
{
get
{
try
{
ExplosionDetail value = _explosionDetail.Value;
if (Enum.IsDefined(typeof(ExplosionDetail), value))
{
return value;
}
}
catch (Exception)
{
}
return ExplosionDetail.Minimal;
}
}
internal int LiveModDynamite
{
get
{
int num = 0;
foreach (Dynamite item in _modDynamite)
{
if ((Object)(object)item != (Object)null)
{
num++;
}
}
return num;
}
}
private void Awake()
{
//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
_enabledOnStart = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled On Start", false, "Start the game with the random dynamite spawner already enabled.");
_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Toggle Key", (KeyCode)289, "Press this key to toggle the spawner on and off.");
_manualBurstKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Manual Burst Key", (KeyCode)290, "Press this key to drop one burst of dynamite right now, regardless of whether the spawner is on.");
_intervalMin = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "Interval Min (s)", 25f, "Minimum seconds between dynamite bursts.");
_intervalMax = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "Interval Max (s)", 70f, "Maximum seconds between dynamite bursts.");
_countMin = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn", "Count Min", 1, "Minimum number of dynamite per burst.");
_countMax = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn", "Count Max", 10, "Maximum number of dynamite per burst.");
_heightMin = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "Height Min", 6f, "Minimum spawn height above a player.");
_heightMax = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "Height Max", 16f, "Maximum spawn height above a player.");
_spreadRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "Spread Radius", 14f, "Horizontal scatter radius (metres) around the chosen player.");
_burstSpreadTime = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "Burst Spread Time (s)", 3f, "How long a burst takes to drop all of its dynamite. Spreading the drops out over a few seconds makes it arrive as a rolling rain instead of one clump. 0 drops everything at once.");
_spawnOnEnable = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "Burst Immediately On Enable", true, "Drop a burst the moment the spawner is toggled on.");
_includeLocalPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "Include Local Player", true, "Also drop dynamite above yourself. Disable to only troll everyone else.");
_onlyAlive = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "Only Above Alive Players", true, "Skip players who are already knocked out.");
_lightFuses = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "Light Fuses", true, "Light the fuse as soon as the dynamite spawns so it actually explodes.");
_verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose Logging", true, "Log every spawned dynamite and skipped spawn. Useful for troubleshooting.");
_suppressSmoke = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Suppress Smoke On Mod Dynamite", true, "Don't spawn the smoke trail for dynamite this mod spawned. Saves a lot of particles when a lot of dynamite is up. Vanilla dynamite is untouched.");
_suppressSparks = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Suppress Sparks On Mod Dynamite", true, "Don't run the burning spark particles for dynamite this mod spawned.");
_explosionDetail = ((BaseUnityPlugin)this).Config.Bind<ExplosionDetail>("Effects", "Explosion Detail", ExplosionDetail.Minimal, "How much of the explosion effect to keep for dynamite THIS MOD spawned. Vanilla dynamite is never affected. Minimal = sound and damage only, no visual objects at all. Particles = keeps the fireball/smoke burst but drops the 13 animated orbs. Full = completely untouched.");
_randomiseFuse = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Randomise Fuse", true, "Give each spawned dynamite a slightly different fuse, so a burst explodes as a rolling barrage instead of 13xN animators hitting on the same frame.");
_fuseJitterMin = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Fuse Jitter Min (x)", 0.8f, "Lowest fuse multiplier used when Randomise Fuse is on.");
_fuseJitterMax = ((BaseUnityPlugin)this).Config.Bind<float>("Effects", "Fuse Jitter Max (x)", 1.6f, "Highest fuse multiplier used when Randomise Fuse is on.");
_maxLiveDynamite = ((BaseUnityPlugin)this).Config.Bind<int>("Effects", "Max Live Mod Dynamite", 20, "Safety cap. If this many of our dynamite are still un-exploded, a new burst is skipped instead of stacking up.");
_messagesEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Messages", "Show Messages", true, "Show an on-screen message when the spawner is toggled or a manual burst is dropped.");
_useGameNotifications = ((BaseUnityPlugin)this).Config.Bind<bool>("Messages", "Use Game Notifications", true, "Try to use PEAK's own notification popup first; falls back to a small overlay if unavailable.");
_messageDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Messages", "Message Duration (s)", 3f, "How long an overlay message stays on screen.");
_persistentIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("Messages", "Persistent Indicator", false, "Keep a small 'Random Dynamite: ON' label in the corner while the spawner is enabled.");
if (_intervalMax.Value < _intervalMin.Value)
{
_intervalMax.Value = _intervalMin.Value;
}
_active = _enabledOnStart.Value;
if (_active)
{
ScheduleNext();
}
Instance = this;
try
{
Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
Log.LogInfo((object)$"Harmony patches applied (smoke={_suppressSmoke.Value}, sparks={_suppressSparks.Value}, explosionDetail={CurrentExplosionDetail}, fuseJitter={_randomiseFuse.Value}).");
}
catch (Exception arg)
{
Log.LogError((object)$"Could not apply Harmony patches: {arg}");
}
Log.LogInfo((object)string.Format("{0} v{1} loaded. Toggle: {2}, manual burst: {3}. Config: BepInEx/config/{4}.cfg", "Random Dynamite", "1.7.0", _toggleKey.Value, _manualBurstKey.Value, "liam.RandomDynamite"));
}
private void Update()
{
//IL_002e: 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)
try
{
if (!_loggedInputDiagnostics)
{
_loggedInputDiagnostics = true;
LogInputDiagnostics();
}
MaybeAnnounceRoomJoin();
PruneTrackedDynamite();
ProcessPendingSpawns();
if (KeyPressed(_toggleKey.Value))
{
_active = !_active;
if (_active)
{
Log.LogInfo((object)"Random Dynamite: ON");
ShowMessage("Random Dynamite: ON");
if (_spawnOnEnable.Value)
{
SpawnBurst("enable");
}
ScheduleNext();
}
else
{
Log.LogInfo((object)"Random Dynamite: OFF");
ShowMessage("Random Dynamite: OFF");
_nextSpawnTime = float.MaxValue;
if (_pendingSpawns.Count > 0)
{
Log.LogInfo((object)string.Format("{0}: cancelled {1} dynamite still queued from the last burst.", "Random Dynamite", _pendingSpawns.Count));
_pendingSpawns.Clear();
}
}
}
if (KeyPressed(_manualBurstKey.Value))
{
Log.LogInfo((object)"Random Dynamite: manual burst requested");
int num = SpawnBurst("manual");
ShowMessage((num > 0) ? string.Format("{0}: dropping {1} dynamite", "Random Dynamite", num) : "Random Dynamite: no players to target");
}
if (_active && Time.time >= _nextSpawnTime)
{
SpawnBurst("auto");
ScheduleNext();
}
}
catch (Exception ex)
{
Log.LogError((object)ex);
}
}
private void MaybeAnnounceRoomJoin()
{
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
bool inRoom = PhotonNetwork.InRoom;
if (!inRoom && _wasInRoom && _pendingSpawns.Count > 0)
{
Log.LogInfo((object)$"Left the room, discarding {_pendingSpawns.Count} queued dynamite.");
_pendingSpawns.Clear();
}
if (inRoom && !_wasInRoom)
{
int num = 0;
try
{
num = Character.AllCharacters?.Count ?? 0;
}
catch
{
}
string text = ResolveDynamitePrefabName();
bool flag = false;
try
{
flag = (Object)(object)Resources.Load<GameObject>("0_Items/" + text) != (Object)null;
}
catch
{
}
Log.LogInfo((object)$"Joined a room. isMaster={PhotonNetwork.IsMasterClient}, characters={num}, dynamitePrefab='{text}', prefabLoads={flag}");
ShowMessage(string.Format("{0} ready - {1} toggle, {2} burst", "Random Dynamite", _toggleKey.Value, _manualBurstKey.Value));
}
else if (!inRoom && _wasInRoom)
{
_modDynamite.Clear();
}
_wasInRoom = inRoom;
}
private void PruneTrackedDynamite()
{
if (Time.time < _nextCleanupTime)
{
return;
}
_nextCleanupTime = Time.time + 5f;
_staleDynamite.Clear();
foreach (Dynamite item in _modDynamite)
{
if ((Object)(object)item == (Object)null)
{
_staleDynamite.Add(item);
}
}
for (int i = 0; i < _staleDynamite.Count; i++)
{
_modDynamite.Remove(_staleDynamite[i]);
}
_staleDynamite.Clear();
}
internal bool IsModDynamite(Dynamite dynamite)
{
if ((Object)(object)dynamite == (Object)null)
{
return false;
}
return _modDynamite.Contains(dynamite);
}
private void ApplyExplosionDetail(Dynamite dynamite)
{
if ((Object)(object)dynamite == (Object)null || (Object)(object)dynamite.explosionPrefab == (Object)null)
{
return;
}
ExplosionDetail currentExplosionDetail = CurrentExplosionDetail;
if (currentExplosionDetail == ExplosionDetail.Full)
{
return;
}
float num = ((dynamite.startingFuseTime > 0.01f) ? dynamite.startingFuseTime : 5f);
float num2 = (_randomiseFuse.Value ? Mathf.Max(1f, _fuseJitterMax.Value) : 1f);
float lifetime = num * num2 + 15f;
try
{
dynamite.explosionPrefab = BuildCheapExplosion(dynamite.explosionPrefab, currentExplosionDetail, lifetime);
}
catch (Exception arg)
{
Log.LogWarning((object)$"Could not build a cheap explosion prefab, leaving the vanilla one: {arg}");
}
}
private static bool DeactivateChild(GameObject target, GameObject root)
{
if ((Object)(object)target == (Object)null || (Object)(object)target == (Object)(object)root || !target.activeSelf)
{
return false;
}
target.SetActive(false);
return true;
}
private GameObject BuildCheapExplosion(GameObject source, ExplosionDetail detail, float lifetime)
{
//IL_0026: 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)
if (!_loggedExplosionPrefab)
{
_loggedExplosionPrefab = true;
LogExplosionPrefabContents(source);
}
GameObject val = Object.Instantiate<GameObject>(source, new Vector3(0f, -100000f, 0f), Quaternion.identity);
((Object)val).name = ((Object)source).name + "(CheapModCopy)";
int num = 0;
ExplosionEffect[] componentsInChildren = val.GetComponentsInChildren<ExplosionEffect>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if (DeactivateChild(((Component)componentsInChildren[i]).gameObject, val))
{
num++;
}
}
if (detail == ExplosionDetail.Minimal)
{
ParticleSystem[] componentsInChildren2 = val.GetComponentsInChildren<ParticleSystem>(true);
for (int i = 0; i < componentsInChildren2.Length; i++)
{
if (DeactivateChild(((Component)componentsInChildren2[i]).gameObject, val))
{
num++;
}
}
Light[] componentsInChildren3 = val.GetComponentsInChildren<Light>(true);
for (int i = 0; i < componentsInChildren3.Length; i++)
{
if (DeactivateChild(((Component)componentsInChildren3[i]).gameObject, val))
{
num++;
}
}
TrailRenderer[] componentsInChildren4 = val.GetComponentsInChildren<TrailRenderer>(true);
for (int i = 0; i < componentsInChildren4.Length; i++)
{
if (DeactivateChild(((Component)componentsInChildren4[i]).gameObject, val))
{
num++;
}
}
MeshRenderer[] componentsInChildren5 = val.GetComponentsInChildren<MeshRenderer>(true);
for (int i = 0; i < componentsInChildren5.Length; i++)
{
if (DeactivateChild(((Component)componentsInChildren5[i]).gameObject, val))
{
num++;
}
}
}
RemoveAfterSeconds component = val.GetComponent<RemoveAfterSeconds>();
if ((Object)(object)component != (Object)null && component.seconds < lifetime)
{
component.seconds = lifetime;
}
int num2 = 0;
componentsInChildren = val.GetComponentsInChildren<ExplosionEffect>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if (((Behaviour)componentsInChildren[i]).isActiveAndEnabled)
{
num2++;
}
}
if (num2 > 0)
{
Log.LogWarning((object)$"Cheap explosion copy still has {num2} active ExplosionEffect component(s), so orbs will still spawn.");
}
if (_verbose.Value)
{
Log.LogInfo((object)($"Cheap explosion copy built ({detail}): {num} visual child object(s) deactivated, " + $"{num2} orb sources still active, lifetime {lifetime:F0}s."));
}
return val;
}
private void LogExplosionPrefabContents(GameObject source)
{
try
{
Log.LogInfo((object)("Explosion prefab '" + ((Object)source).name + "' components:"));
Component[] componentsInChildren = source.GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if ((Object)(object)val != (Object)null)
{
Log.LogInfo((object)(" " + ((object)val).GetType().Name));
}
}
ExplosionEffect componentInChildren = source.GetComponentInChildren<ExplosionEffect>(true);
if ((Object)(object)componentInChildren != (Object)null)
{
int num = 1 + componentInChildren.explosionPointCount + componentInChildren.subExplosionPointCount * componentInChildren.explosionPointCount;
Log.LogInfo((object)$" -> {num} orb objects per explosion, each with its own Animator");
}
AudioSource[] componentsInChildren2 = source.GetComponentsInChildren<AudioSource>(true);
foreach (AudioSource val2 in componentsInChildren2)
{
Log.LogInfo((object)$" -> audio '{((Object)val2).name}' spatialBlend={val2.spatialBlend} (0 would play at any distance)");
}
}
catch (Exception ex)
{
Log.LogWarning((object)("Could not log explosion prefab contents: " + ex.Message));
}
}
private void LogInputDiagnostics()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
bool flag = false;
try
{
flag = Keyboard.current != null;
}
catch
{
}
Log.LogInfo((object)$"Input diagnostics: newInputSystemKeyboard={flag}, legacyInputAvailable={_legacyInputAvailable}, toggleKey={_toggleKey.Value}, burstKey={_manualBurstKey.Value}");
}
private void ScheduleNext()
{
float num = Mathf.Max(0.5f, _intervalMin.Value);
float num2 = Mathf.Max(num, _intervalMax.Value);
_nextSpawnTime = Time.time + Random.Range(num, num2);
}
private int SpawnBurst(string reason)
{
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
if (!PhotonNetwork.InRoom)
{
Log.LogWarning((object)("Dynamite burst (" + reason + ") skipped: not in a Photon room yet."));
return 0;
}
int num = _pendingSpawns.Count + LiveModDynamite;
int num2 = Mathf.Max(1, _maxLiveDynamite.Value);
if (num >= num2)
{
Log.LogWarning((object)$"Dynamite burst ({reason}) skipped: {num} of our dynamite are still outstanding (cap {num2}).");
return 0;
}
int num3 = Random.Range(_countMin.Value, Mathf.Max(_countMin.Value, _countMax.Value) + 1);
int num4 = 0;
float num5 = Mathf.Max(0f, _burstSpreadTime.Value);
float num6 = ((num3 > 1) ? (num5 / (float)(num3 - 1)) : 0f);
float time = Time.time;
for (int i = 0; i < num3; i++)
{
if (!TryGetSpawnPoint(out var point))
{
Log.LogWarning((object)$"Dynamite burst ({reason}): no valid player to spawn above after {num4} queued.");
break;
}
float num7 = ((num6 <= 0f) ? 0f : ((float)i * num6 + Random.Range((0f - num6) * 0.3f, num6 * 0.3f)));
_pendingSpawns.Enqueue(new PendingSpawn
{
Time = time + Mathf.Max(0f, num7),
Position = point
});
num4++;
}
if (num4 > 0)
{
Log.LogInfo((object)$"Dynamite burst ({reason}): queued {num4} dynamite over {num5:F1}s ({_pendingSpawns.Count} still pending).");
}
return num4;
}
private void ProcessPendingSpawns()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
while (_pendingSpawns.Count > 0 && _pendingSpawns.Peek().Time <= Time.time)
{
PendingSpawn pendingSpawn = _pendingSpawns.Dequeue();
if (!PhotonNetwork.InRoom)
{
Log.LogWarning((object)"Dropped a queued dynamite: left the room.");
}
else
{
SpawnDynamite(pendingSpawn.Position);
}
}
}
private bool TryGetSpawnPoint(out Vector3 point)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//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_00fc: 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_0111: 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)
//IL_0114: 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_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
point = Vector3.zero;
Targets.Clear();
List<Character> allCharacters = Character.AllCharacters;
if (allCharacters == null || allCharacters.Count == 0)
{
return false;
}
for (int i = 0; i < allCharacters.Count; i++)
{
Character val = allCharacters[i];
if (!((Object)(object)val == (Object)null) && (_includeLocalPlayer.Value || !((Object)(object)val == (Object)(object)Character.localCharacter)) && (!_onlyAlive.Value || !((Object)(object)val.data != (Object)null) || !val.data.dead))
{
Targets.Add(val);
}
}
if (Targets.Count == 0)
{
return false;
}
Vector3 center = Targets[Random.Range(0, Targets.Count)].Center;
float num = Random.Range(_heightMin.Value, Mathf.Max(_heightMin.Value, _heightMax.Value));
Vector2 val2 = Random.insideUnitCircle * _spreadRadius.Value;
point = center + new Vector3(val2.x, num, val2.y);
return true;
}
private bool SpawnDynamite(Vector3 position)
{
//IL_0014: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_023f: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Expected O, but got Unknown
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Expected O, but got Unknown
string text = ResolveDynamitePrefabName();
string text2 = "0_Items/" + text;
try
{
GameObject val = PhotonNetwork.Instantiate(text2, position, Random.rotation, (byte)0, (object[])null);
if ((Object)(object)val == (Object)null)
{
Log.LogWarning((object)$"Instantiate returned null for '{text2}' at {position}.");
return false;
}
Item component = val.GetComponent<Item>();
PhotonView component2 = val.GetComponent<PhotonView>();
Dynamite component3 = val.GetComponent<Dynamite>();
if ((Object)(object)component3 != (Object)null)
{
_modDynamite.Add(component3);
ApplyExplosionDetail(component3);
}
if ((Object)(object)component != (Object)null)
{
try
{
component.SetKinematicNetworked(false);
}
catch (Exception ex)
{
Log.LogWarning((object)("SetKinematicNetworked failed: " + ex.Message));
}
}
if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
{
try
{
ItemInstanceData val2 = new ItemInstanceData(System.Guid.NewGuid());
if (_randomiseFuse.Value && (Object)(object)component3 != (Object)null && component3.startingFuseTime > 0.01f)
{
float num = Mathf.Min(_fuseJitterMin.Value, _fuseJitterMax.Value);
float num2 = Mathf.Max(_fuseJitterMin.Value, _fuseJitterMax.Value);
float num3 = Random.Range(num, num2);
float num4 = component3.startingFuseTime * num3;
val2.RegisterEntry<FloatItemData>((DataEntryKey)10, new FloatItemData
{
Value = num4
});
if (_verbose.Value)
{
Log.LogInfo((object)$"Fuse jitter: {component3.startingFuseTime:F2}s x {num3:F2} = {num4:F2}s");
}
}
ItemInstanceDataHandler.AddInstanceData(val2);
component2.RPC("SetItemInstanceDataRPC", (RpcTarget)0, new object[1] { val2 });
}
catch (Exception ex2)
{
Log.LogWarning((object)("Could not set dynamite instance data: " + ex2.Message));
}
}
if (_lightFuses.Value && (Object)(object)component3 != (Object)null)
{
try
{
component3.LightFlare();
}
catch (Exception ex3)
{
Log.LogWarning((object)("LightFlare failed: " + ex3.Message));
}
}
if (_verbose.Value)
{
Log.LogInfo((object)$"Spawned dynamite '{text}' at {position}.");
}
return true;
}
catch (Exception arg)
{
Log.LogError((object)$"Failed to spawn dynamite: {arg}");
return false;
}
}
private string ResolveDynamitePrefabName()
{
//IL_0047: 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 (!string.IsNullOrEmpty(_dynamitePrefabName))
{
return _dynamitePrefabName;
}
try
{
Dynamite[] array = Resources.FindObjectsOfTypeAll<Dynamite>();
if (array != null)
{
for (int i = 0; i < 2; i++)
{
if (!string.IsNullOrEmpty(_dynamitePrefabName))
{
break;
}
foreach (Dynamite val in array)
{
if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
{
continue;
}
Scene scene = ((Component)val).gameObject.scene;
bool flag = ((Scene)(ref scene)).IsValid();
if (!(i == 0 && flag))
{
string text = ItemPrefabName(val);
if (!string.IsNullOrEmpty(text))
{
_dynamitePrefabName = text;
break;
}
}
}
}
}
}
catch (Exception ex)
{
Log.LogWarning((object)("Could not resolve Dynamite prefab name: " + ex.Message));
}
if (string.IsNullOrEmpty(_dynamitePrefabName))
{
_dynamitePrefabName = "Dynamite";
Log.LogWarning((object)"Falling back to hard-coded dynamite prefab name 'Dynamite'.");
}
else
{
Log.LogInfo((object)("Resolved dynamite prefab name: '" + _dynamitePrefabName + "'."));
}
return _dynamitePrefabName;
}
private static string ItemPrefabName(Dynamite dynamite)
{
Item component = ((Component)dynamite).GetComponent<Item>();
GameObject val = (((Object)(object)component != (Object)null) ? ((Component)component).gameObject : ((Component)dynamite).gameObject);
string text = (((Object)(object)val != (Object)null) ? ((Object)val).name : null);
if (string.IsNullOrEmpty(text))
{
return null;
}
if (text.EndsWith("(Clone)", StringComparison.Ordinal))
{
text = text.Substring(0, text.Length - "(Clone)".Length).Trim();
}
return text;
}
private void ShowMessage(string text)
{
//IL_006a: 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)
if (!_messagesEnabled.Value || string.IsNullOrEmpty(text))
{
return;
}
if (_useGameNotifications.Value && !_nativeNotificationsUnavailable)
{
try
{
if ((Object)(object)_notifications == (Object)null)
{
UI_Notifications[] array = Resources.FindObjectsOfTypeAll<UI_Notifications>();
if (array != null)
{
foreach (UI_Notifications val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
GameObject gameObject = ((Component)val).gameObject;
if ((Object)(object)gameObject != (Object)null)
{
Scene scene = gameObject.scene;
if (((Scene)(ref scene)).IsValid() && gameObject.activeInHierarchy)
{
_notifications = val;
break;
}
}
}
}
}
if ((Object)(object)_notifications != (Object)null)
{
_notifications.AddNotification(text);
return;
}
}
catch
{
_nativeNotificationsUnavailable = true;
_notifications = null;
}
}
_toastText = text;
_toastUntil = Time.time + Mathf.Max(0.5f, _messageDuration.Value);
}
private void OnGUI()
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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)
try
{
int num;
if (_toastText != null)
{
num = ((Time.time < _toastUntil) ? 1 : 0);
if (num != 0)
{
goto IL_0030;
}
}
else
{
num = 0;
}
if (_persistentIndicator.Value && _active)
{
goto IL_0030;
}
goto IL_0036;
IL_0030:
EnsureStyles();
goto IL_0036;
IL_0036:
if (num != 0)
{
Rect val = new Rect(((float)Screen.width - 520f) * 0.5f, (float)Screen.height * 0.12f, 520f, 46f);
GUI.DrawTexture(val, (Texture)(object)_toastBackground);
GUI.Label(val, _toastText, _toastStyle);
}
if (_persistentIndicator.Value && _active)
{
GUI.Label(new Rect((float)Screen.width - 260f, (float)Screen.height - 42f, 248f, 30f), "Random Dynamite: ON", _indicatorStyle);
}
}
catch
{
}
}
private void EnsureStyles()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected O, but got Unknown
//IL_008c: 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_00ab: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
if (_toastStyle == null)
{
_toastBackground = new Texture2D(1, 1);
_toastBackground.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.72f));
_toastBackground.Apply();
_toastStyle = new GUIStyle(GUI.skin.label);
_toastStyle.alignment = (TextAnchor)4;
_toastStyle.fontSize = 22;
_toastStyle.fontStyle = (FontStyle)1;
_toastStyle.normal.textColor = Color.white;
_indicatorStyle = new GUIStyle(GUI.skin.label);
_indicatorStyle.alignment = (TextAnchor)5;
_indicatorStyle.fontSize = 16;
_indicatorStyle.fontStyle = (FontStyle)1;
_indicatorStyle.normal.textColor = new Color(1f, 0.62f, 0.2f, 1f);
}
}
private unsafe bool KeyPressed(KeyCode key)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
bool flag = false;
try
{
Keyboard current = Keyboard.current;
if (current != null && Enum.TryParse<Key>(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(), out Key result))
{
flag = ((ButtonControl)current[result]).wasPressedThisFrame;
}
}
catch
{
}
if (!flag && _legacyInputAvailable)
{
try
{
flag = Input.GetKeyDown(key);
}
catch
{
_legacyInputAvailable = false;
}
}
return flag;
}
}