Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Dozer v1.0.2
BepInEx/plugins/DozerEntity.dll
Decompiled 6 months agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DozerEntity")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DozerEntity")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("707b5311-bc50-4ec1-ac25-901818a7c6a1")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace DozerEntity; public class DozerBehaviour : MonoBehaviour { private enum DozerState { Hidden, ClosedEyes, OpenEyes, Screamer } private DozerState currentState = DozerState.Hidden; private float timer = 0f; private float nextAppearTime = 0f; private float cooldownTimer = 0f; private float cooldownTime = 0f; private bool isOnCooldown = false; private float previousVolume = 1f; private GameObject overlayObject; private Image overlayImage; private Image blackBackground; private AudioSource audioSource; private AudioClip closedSound; private Sprite[] closedSprites = (Sprite[])(object)new Sprite[2]; private Sprite openSprite; private Sprite[] screamerSprites = (Sprite[])(object)new Sprite[6]; private float animTimer = 0f; private int animFrame = 0; private float animSpeed = 0.3f; private string modFolder; private AudioClip LoadAudioClip(string filename) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown string text = Path.Combine(modFolder, filename); if (!File.Exists(text)) { Debug.LogError((object)("Dozer Entity: звук не найден — " + text)); return null; } WWW val = new WWW("file://" + text); try { while (!val.isDone) { } return val.GetAudioClip(false, false, (AudioType)20); } finally { ((IDisposable)val)?.Dispose(); } } private void Start() { string pluginPath = Paths.PluginPath; string[] directories = Directory.GetDirectories(pluginPath, "DozerEntity", SearchOption.AllDirectories); if (directories.Length != 0) { modFolder = directories[0]; } else { modFolder = Path.Combine(pluginPath, "DozerEntity"); } Debug.Log((object)("Dozer Entity: папка мода — " + modFolder)); LoadSprites(); closedSound = LoadAudioClip("closed_sound.wav"); audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); audioSource.loop = true; audioSource.volume = 1f; CreateOverlay(); nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); } private void LoadSprites() { closedSprites[0] = LoadSprite("closed_1.png"); closedSprites[1] = LoadSprite("closed_2.png"); openSprite = LoadSprite("open.png"); for (int i = 0; i < 6; i++) { screamerSprites[i] = LoadSprite($"screamer_{i + 1}.png"); } } private void ForceHide() { currentState = DozerState.Hidden; timer = 0f; overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); AudioListener.volume = previousVolume; isOnCooldown = false; audioSource.Stop(); } private Sprite LoadSprite(string filename) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(modFolder, filename); if (!File.Exists(text)) { Debug.LogError((object)("Dozer Entity: файл не найден — " + text)); return null; } byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private void Update() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return; } if (currentState == DozerState.Hidden || currentState == DozerState.ClosedEyes || currentState == DozerState.OpenEyes) { previousVolume = AudioListener.volume; } if (isOnCooldown) { cooldownTimer += Time.deltaTime; if (cooldownTimer >= cooldownTime) { isOnCooldown = false; cooldownTimer = 0f; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); } } else if (val.isPlayerDead) { if (currentState != 0) { overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); audioSource.Stop(); currentState = DozerState.Hidden; timer = 0f; isOnCooldown = false; } } else { if (!IsPlayerInGame()) { return; } if (val.quickMenuManager.isMenuOpen) { overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); return; } timer += Time.deltaTime; switch (currentState) { case DozerState.Hidden: if (isOnCooldown) { cooldownTimer += Time.deltaTime; if (cooldownTimer >= cooldownTime) { isOnCooldown = false; cooldownTimer = 0f; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); } } else if (timer >= nextAppearTime) { ShowClosedEyes(); } break; case DozerState.ClosedEyes: AnimateClosed(); if (timer >= Plugin.EyeOpenDelay.Value) { OpenEyes(); } break; case DozerState.OpenEyes: if (!IsPlayerSafe()) { TriggerScreamer(); } else if (timer >= Plugin.OpenEyesDuration.Value) { Hide(); } break; case DozerState.Screamer: AnimateScreamer(); if (timer >= 1.5f) { KillPlayer(); } break; } } } private void AnimateClosed() { if (currentState != DozerState.ClosedEyes) { return; } animTimer += Time.deltaTime; if (animTimer >= animSpeed) { animTimer = 0f; animFrame = (animFrame + 1) % 2; if ((Object)(object)closedSprites[animFrame] != (Object)null) { overlayImage.sprite = closedSprites[animFrame]; } } } private void AnimateScreamer() { animTimer += Time.deltaTime; if (animTimer >= 0.1f) { animTimer = 0f; animFrame++; if (animFrame >= 6) { overlayObject.SetActive(false); } else if ((Object)(object)screamerSprites[animFrame] != (Object)null) { overlayImage.sprite = screamerSprites[animFrame]; } } } private void ShowClosedEyes() { currentState = DozerState.ClosedEyes; timer = 0f; animFrame = 0; animTimer = 0f; overlayObject.SetActive(true); if ((Object)(object)closedSprites[0] != (Object)null) { overlayImage.sprite = closedSprites[0]; } if ((Object)(object)closedSound != (Object)null) { audioSource.clip = closedSound; audioSource.Play(); } } private void OpenEyes() { currentState = DozerState.OpenEyes; timer = 0f; animFrame = 0; animTimer = 0f; if ((Object)(object)openSprite != (Object)null) { overlayImage.sprite = openSprite; } audioSource.Stop(); } private void TriggerScreamer() { currentState = DozerState.Screamer; timer = 0f; animFrame = 0; animTimer = 0f; previousVolume = AudioListener.volume; AudioListener.volume = 0f; ((Component)blackBackground).gameObject.SetActive(true); overlayObject.SetActive(false); overlayObject.SetActive(true); if ((Object)(object)screamerSprites[0] != (Object)null) { overlayImage.sprite = screamerSprites[0]; } } public void ResetDozer() { currentState = DozerState.Hidden; timer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); overlayObject.SetActive(false); } private void Hide() { currentState = DozerState.Hidden; timer = 0f; overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); isOnCooldown = true; cooldownTimer = 0f; nextAppearTime = Random.Range(Plugin.MinSpawnTime.Value, Plugin.MaxSpawnTime.Value); audioSource.Stop(); } private void KillPlayer() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController != (Object)null) { localPlayerController.KillPlayer(Vector3.zero, true, (CauseOfDeath)0, 1, default(Vector3)); } AudioListener.volume = previousVolume; overlayObject.SetActive(false); ((Component)blackBackground).gameObject.SetActive(false); audioSource.Stop(); currentState = DozerState.Hidden; timer = 0f; isOnCooldown = false; } private bool IsPlayerSafe() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return true; } bool isCrouching = val.isCrouching; Vector3 velocity = val.thisController.velocity; bool flag = ((Vector3)(ref velocity)).magnitude > 0.1f; return isCrouching && !flag; } private bool IsPlayerInGame() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return false; } if (val.isPlayerDead) { return false; } return !val.isInHangarShipRoom && (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded; } private void CreateOverlay() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00ff: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DozerCanvas"); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 100; Object.DontDestroyOnLoad((Object)(object)val); GameObject val3 = new GameObject("DozerBlackBg"); val3.transform.SetParent(val.transform, false); blackBackground = val3.AddComponent<Image>(); ((Graphic)blackBackground).color = new Color(0f, 0f, 0f, 1f); RectTransform component = val3.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; val3.SetActive(false); overlayObject = new GameObject("DozerImage"); overlayObject.transform.SetParent(val.transform, false); overlayImage = overlayObject.AddComponent<Image>(); RectTransform component2 = overlayObject.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(400f, 400f); component2.anchoredPosition = Vector2.zero; overlayObject.SetActive(false); } } [HarmonyPatch(typeof(PlayerControllerB), "Start")] public class DozerPatch { private static void Postfix(PlayerControllerB __instance) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if (((NetworkBehaviour)__instance).IsOwner && !((Object)(object)Object.FindObjectOfType<DozerBehaviour>() != (Object)null)) { int num = Random.Range(0, 100); if (num >= Plugin.SpawnChance.Value) { Debug.Log((object)$"Dozer Entity: не появится в этом раунде (бросок {num}, нужно < {Plugin.SpawnChance.Value})"); return; } GameObject val = new GameObject("DozerManager"); val.AddComponent<DozerBehaviour>(); Object.DontDestroyOnLoad((Object)(object)val); Debug.Log((object)$"Dozer Entity: менеджер создан! (бросок {num})"); } } } [HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadAnimation")] public class DozerRespawnPatch { private static void Postfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner) { DozerBehaviour dozerBehaviour = Object.FindObjectOfType<DozerBehaviour>(); if ((Object)(object)dozerBehaviour != (Object)null) { dozerBehaviour.ResetDozer(); Debug.Log((object)"Dozer Entity: сброс после возрождения!"); } } } } [BepInPlugin("com.yourname.dozerentity", "Dozer Entity", "1.0.1")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.yourname.dozerentity"); public static ConfigEntry<int> SpawnChance; public static ConfigEntry<float> EyeOpenDelay; public static ConfigEntry<float> OpenEyesDuration; public static ConfigEntry<float> MinSpawnTime; public static ConfigEntry<float> MaxSpawnTime; private void Awake() { SpawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 35, "Dozer appear chance each round (0-100)"); EyeOpenDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "EyeOpenDelay", 1.5f, "Time in seconds before Dozer opens it's eyes"); OpenEyesDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "OpenEyesDuration", 3f, "How long Dozer stays with open eyes in seconds"); MinSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MinSpawnTime", 10f, "Minimum time in seconds before Dozer appears"); MaxSpawnTime = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "MaxSpawnTime", 30f, "Maximum time in seconds before Dozer appears"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Dozer Entity загружен!"); harmony.PatchAll(); } }