Minefun Weather FX Pack

Mưa + Lava Sky + Sấm sét cho Minefun

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(У мене вже є менеджер скриптів, дайте мені встановити його!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Minefun Weather FX Pack
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Mưa + Lava Sky + Sấm sét cho Minefun
// @author       You
// @match        *://minefun.io/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // =========================
    // CANVAS
    // =========================
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");

    canvas.style.position = "fixed";
    canvas.style.top = "0";
    canvas.style.left = "0";
    canvas.style.width = "100%";
    canvas.style.height = "100%";
    canvas.style.pointerEvents = "none";
    canvas.style.zIndex = "999999";

    document.body.appendChild(canvas);

    function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }

    resizeCanvas();
    window.addEventListener("resize", resizeCanvas);

    // =========================
    // STATES
    // =========================
    let rainEnabled = false;
    let lavaEnabled = false;
    let thunderEnabled = false;

    // =========================
    // SKY OVERLAY
    // =========================
    const overlay = document.createElement("div");

    overlay.style.position = "fixed";
    overlay.style.top = "0";
    overlay.style.left = "0";
    overlay.style.width = "100%";
    overlay.style.height = "100%";
    overlay.style.pointerEvents = "none";
    overlay.style.zIndex = "999998";
    overlay.style.transition = "0.3s";

    document.body.appendChild(overlay);

    // =========================
    // AUDIO
    // =========================
    const rainAudio = new Audio(
        "https://cdn.pixabay.com/download/audio/2022/03/15/audio_c8d1d6d95f.mp3?filename=rain-ambient-110397.mp3"
    );

    rainAudio.loop = true;
    rainAudio.volume = 0.25;

    const thunderSounds = [
        new Audio("https://cdn.pixabay.com/download/audio/2021/08/04/audio_12b0c7443e.mp3?filename=thunder-25689.mp3"),
        new Audio("https://cdn.pixabay.com/download/audio/2022/03/10/audio_270cc5b8d2.mp3?filename=thunderstorm-ambient-110388.mp3"),
        new Audio("https://cdn.pixabay.com/download/audio/2021/08/09/audio_88447d0c96.mp3?filename=thunder-strike-25700.mp3")
    ];

    document.addEventListener("click", () => {
        rainAudio.play().then(() => {
            rainAudio.pause();
        }).catch(() => {});
    }, { once: true });

    // =========================
    // RAIN
    // =========================
    const rainDrops = [];

    function createRain() {
        rainDrops.length = 0;

        for (let i = 0; i < 300; i++) {
            rainDrops.push({
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height,
                speed: 18 + Math.random() * 8
            });
        }
    }

    createRain();

    // =========================
    // LAVA PARTICLES
    // =========================
    const lavaParticles = [];

    function createLava() {
        lavaParticles.length = 0;

        for (let i = 0; i < 120; i++) {
            lavaParticles.push({
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height,
                r: 2 + Math.random() * 5,
                speed: 1 + Math.random() * 2
            });
        }
    }

    createLava();

    // =========================
    // THUNDER
    // =========================
    let flashAlpha = 0;

    function triggerThunder() {
        if (!thunderEnabled) return;

        flashAlpha = 1;

        const randomSound =
            thunderSounds[Math.floor(Math.random() * thunderSounds.length)];

        randomSound.volume = 0.5;
        randomSound.currentTime = 0;

        randomSound.play().catch(() => {});

        setTimeout(() => {
            flashAlpha = 0;
        }, 120);
    }

    setInterval(() => {
        if (thunderEnabled) {
            if (Math.random() < 0.35) {
                triggerThunder();
            }
        }
    }, 2500);

    // =========================
    // DRAW LOOP
    // =========================
    function animate() {

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // ===== RAIN =====
        if (rainEnabled) {

            ctx.strokeStyle = "rgba(170,190,255,0.45)";
            ctx.lineWidth = 1;

            for (const r of rainDrops) {

                ctx.beginPath();
                ctx.moveTo(r.x, r.y);
                ctx.lineTo(r.x - 2, r.y + 15);
                ctx.stroke();

                r.y += r.speed;

                if (r.y > canvas.height) {
                    r.y = -20;
                    r.x = Math.random() * canvas.width;
                }
            }
        }

        // ===== LAVA =====
        if (lavaEnabled) {

            for (const l of lavaParticles) {

                ctx.beginPath();

                ctx.fillStyle =
                    `rgba(255, ${80 + Math.random() * 120}, 0, 0.7)`;

                ctx.arc(l.x, l.y, l.r, 0, Math.PI * 2);

                ctx.fill();

                l.y += l.speed;

                if (l.y > canvas.height) {
                    l.y = -10;
                    l.x = Math.random() * canvas.width;
                }
            }
        }

        // ===== THUNDER FLASH =====
        if (flashAlpha > 0) {

            ctx.fillStyle = `rgba(255,255,255,${flashAlpha})`;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            flashAlpha -= 0.05;
        }

        requestAnimationFrame(animate);
    }

    animate();

    // =========================
    // UI
    // =========================
    const panel = document.createElement("div");

    panel.style.position = "fixed";
    panel.style.top = "90px";
    panel.style.left = "12px";
    panel.style.zIndex = "1000000";
    panel.style.background = "rgba(0,0,0,0.45)";
    panel.style.backdropFilter = "blur(4px)";
    panel.style.padding = "5px";
    panel.style.borderRadius = "10px";
    panel.style.display = "flex";
    panel.style.flexDirection = "column";
    panel.style.gap = "4px";
    panel.style.userSelect = "none";
    panel.style.fontFamily = "Arial";

    document.body.appendChild(panel);

    function createButton(text, color) {

        const btn = document.createElement("button");

        btn.textContent = text;

        btn.style.width = "42px";
        btn.style.height = "24px";
        btn.style.fontSize = "10px";
        btn.style.border = "none";
        btn.style.borderRadius = "6px";
        btn.style.cursor = "pointer";
        btn.style.background = color;
        btn.style.color = "white";

        return btn;
    }

    const rainBtn = createButton("RAIN", "#3498db");
    const lavaBtn = createButton("LAVA", "#ff5e00");
    const thunderBtn = createButton("⚡", "#888");

    panel.appendChild(rainBtn);
    panel.appendChild(lavaBtn);
    panel.appendChild(thunderBtn);

    // =========================
    // BUTTON EVENTS
    // =========================

    rainBtn.onclick = () => {

        rainEnabled = !rainEnabled;

        if (rainEnabled) {

            overlay.style.background =
                "linear-gradient(rgba(20,20,20,0.3), rgba(0,0,0,0.15))";

            rainAudio.play().catch(() => {});

            rainBtn.style.opacity = "1";

        } else {

            rainAudio.pause();

            rainBtn.style.opacity = "0.5";

            if (!lavaEnabled) {
                overlay.style.background = "transparent";
            }
        }
    };

    lavaBtn.onclick = () => {

        lavaEnabled = !lavaEnabled;

        if (lavaEnabled) {

            overlay.style.background =
                "linear-gradient(rgba(255,120,0,0.22), rgba(255,50,0,0.15))";

            lavaBtn.style.opacity = "1";

        } else {

            lavaBtn.style.opacity = "0.5";

            if (!rainEnabled) {
                overlay.style.background = "transparent";
            }
        }
    };

    thunderBtn.onclick = () => {

        thunderEnabled = !thunderEnabled;

        thunderBtn.style.opacity =
            thunderEnabled ? "1" : "0.5";
    };

    // =========================
    // DEFAULT DIM
    // =========================
    rainBtn.style.opacity = "0.5";
    lavaBtn.style.opacity = "0.5";
    thunderBtn.style.opacity = "0.5";

    // =========================
    // DRAG PANEL
    // =========================
    let dragging = false;
    let offsetX = 0;
    let offsetY = 0;

    panel.addEventListener("mousedown", (e) => {

        dragging = true;

        offsetX = e.clientX - panel.offsetLeft;
        offsetY = e.clientY - panel.offsetTop;
    });

    document.addEventListener("mouseup", () => {
        dragging = false;
    });

    document.addEventListener("mousemove", (e) => {

        if (!dragging) return;

        panel.style.left = (e.clientX - offsetX) + "px";
        panel.style.top = (e.clientY - offsetY) + "px";
    });

})();