Greasy Fork

Greasy Fork is available in English.

落雷

雷霆万钧!

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         落雷
// @namespace    http://tampermonkey.net/
// @version      1.8
// @description  雷霆万钧!
// @author       TaichiSlippers (Modified by whosyourdaddy)
// @match        https://www.milkywayidle.com/*
// @match        https://test.milkywayidle.com/*
// @icon         https://www.milkywayidle.com/favicon.svg
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 页面可见性检测
    let isPageVisible = true;
    const visibilityChangeEvent = (() => {
        if (typeof document.hidden !== 'undefined') {
            return 'visibilitychange';
        } else if (typeof document.msHidden !== 'undefined') {
            return 'msvisibilitychange';
        } else if (typeof document.webkitHidden !== 'undefined') {
            return 'webkitvisibilitychange';
        }
        return null;
    })();

    const hiddenProp = (() => {
        if (typeof document.hidden !== 'undefined') {
            return 'hidden';
        } else if (typeof document.msHidden !== 'undefined') {
            return 'msHidden';
        } else if (typeof document.webkitHidden !== 'undefined') {
            return 'webkitHidden';
        }
        return null;
    })();

    if (visibilityChangeEvent && hiddenProp) {
        document.addEventListener(visibilityChangeEvent, () => {
            isPageVisible = !document[hiddenProp];
            console.log(`页面可见性变化: ${isPageVisible ? '可见' : '隐藏'}`);
        });
    }

    // 创建全屏 Canvas
    const canvas = document.createElement('canvas');
    canvas.id = 'eggTrackerCanvas';
    Object.assign(canvas.style, { position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 999 });
    document.body.appendChild(canvas);
    const ctx = canvas.getContext('2d');
    function resize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }
    resize(); window.addEventListener('resize', resize);

    // ===== 复合特效类 =====
    class CombinedThunderEffect {
        constructor(canvas) {
            this.canvas = canvas;
            this.ctx = canvas.getContext('2d');
            this.thunders = [];
            this.particles = [];
            this.explosions = [];

            // 全局时间倍率
            this.timeScale = 1.2; //按需求修改 ←←←←←← timeScale > 1 会减慢所有动画(包括消失速度) timeScale < 1 会加速所有动画

            // 融合颜色配置
            this.lightningColors = [
                '#3B82F6', // 主蓝(千鸟)
                '#87CEFA', // 天蓝
                '#FFFFFF', // 白色
                '#DBEAFE', // 淡蓝
                '#1E40AF', // 深蓝
            ];

            // 爆炸颜色配置
            this.explosionColors = [
                '#3B82F6', // 蓝色
                '#2563EB', // 中蓝
                '#FFFFFF', // 白色
                '#93C5FD', // 浅蓝
            ];

            // 绑定事件处理函数
            this.animate = this.animate.bind(this);
            this.resize = this.resize.bind(this);

            // 监听窗口大小变化
            window.addEventListener('resize', this.resize);

            // 开始动画循环
            this.isPaused = false;
            this.lastTimestamp = 0;
            requestAnimationFrame(this.animate);
        }

        // 暂停/恢复渲染
        setPaused(paused) {
            this.isPaused = paused;
            if (!paused) {
                // 恢复时重置时间戳,避免大的时间跳跃
                this.lastTimestamp = 0;
                requestAnimationFrame(this.animate);
            }
            console.log(`特效渲染 ${paused ? '已暂停' : '已恢复'}`);
        }

        // 调整Canvas大小
        resize() {
            this.canvas.width = window.innerWidth;
            this.canvas.height = window.innerHeight;
        }

        // 创建复合特效
        createCombinedEffect(targetX, targetY, radius, intensity = 1, damage = 100) {
            // 如果页面不可见或渲染已暂停,不创建新特效
            if (!isPageVisible || this.isPaused) return;

            // 计算攻击范围
            const minX = Math.max(0, targetX - radius);
            const maxX = Math.min(this.canvas.width, targetX + radius);
            const minY = 0; // 从屏幕顶部开始
            const maxY = targetY;

            // 计算闪电数量
            const count = 10 + Math.floor(intensity * 8);//按需求修改 ←←←←←← 10为闪电数量

            // 生成闪电的时间间隔
            const interval = 2 / count;//按需求修改 ←←←←←←

            // 创建多道闪电

           for (var i = 0; i < count; i++) {
           const currentIsPageVisible = isPageVisible;
           setTimeout(() => {
        // 如果页面不可见或渲染已暂停,不创建新闪电
           if (!currentIsPageVisible || this.isPaused) return;
        // 随机闪电起点和终点
           const startX = minX + Math.random() * (maxX - minX);
           const startY = minY + Math.random() * (maxY * 0.3); // 从屏幕上方开始
           const endX = targetX - radius*0.7 + Math.random() * (radius*1.4);
           const endY = targetY - radius*0.5 + Math.random() * (radius);
        // 创建融合闪电
        const thunder = this.createCombinedLightning(startX, startY, endX, endY, damage);
        // 调整闪电参数
        thunder.alpha = 1;//1不透明 0透明
        thunder.fadeSpeed = 0.03 / this.timeScale;
    }, i * interval);
}

            // 创建中心主闪电
            setTimeout(() => {
                // 如果页面不可见或渲染已暂停,不创建新闪电
                if (!isPageVisible || this.isPaused) return;

                const thunder = this.createCombinedLightning(
                    targetX,
                    -50, // 从屏幕外开始
                    targetX,
                    targetY,
                    25, // 增加主闪电分段数    按需求修改 ←←←←←← 默认20分段
                    0.4, // 增加主闪电分支概率 按需求修改 ←←←←←← 默认40%概率分支
                    3, // 增加主闪电分支层级   按需求修改 ←←←←←← 默认层级3
                    damage
                );

                // 调整主闪电参数
                thunder.alpha = 1; //1不透明 0透明
                thunder.fadeSpeed = 0.04 / this.timeScale;

                // 创建中心爆炸效果
                const explosion = this.createCombinedExplosion(targetX, targetY, 40 + Math.min(60, 15 * intensity), damage);

                // 创建千鸟风格粒子
                this.createChidoriParticles(targetX, targetY, damage);
            }, 1); // 延迟时间
        }

        // 创建融合闪电
        createCombinedLightning(startX, startY, endX, endY, segments = 15, branchChance = 0.2, branchLevel = 2, damage = 100) {
            const thunder = {
                startX,
                startY,
                endX,
                endY,
                segments,
                branchChance,
                branchLevel,
                alpha: 1,
                fadeSpeed: 0.05,
                damage,
                color: this.lightningColors[Math.floor(Math.random() * this.lightningColors.length)],
                branches: [],
                isMain: Math.random() < 0.4, // 40%概率出现主闪电 按需求修改 ←←←←←←
            };

            // 生成主闪电路径
            thunder.points = this.generateCombinedLightningPath(startX, startY, endX, endY, segments);

            // 生成分支闪电
            if (branchLevel > 0) {
                this.generateCombinedBranches(thunder, branchLevel);
            }

            this.thunders.push(thunder);
            return thunder;
        }

        // 生成融合闪电路径
        generateCombinedLightningPath(startX, startY, endX, endY, segments) {
            const points = [{ x: startX, y: startY }];
            const dx = endX - startX;
            const dy = endY - startY;
            const totalLength = Math.sqrt(dx * dx + dy * dy);
            const segmentLength = totalLength / segments;
            const angle = Math.atan2(dy, dx);

            // 生成中间点
            for (let i = 1; i < segments; i++) {
                const posOnLine = i / segments;
                const baseX = startX + dx * posOnLine;
                const baseY = startY + dy * posOnLine;

                // 添加随机偏移
                const offset = (Math.random() - 0.5) * totalLength * 0.1 * (1 - posOnLine);
                const perpAngle = angle + Math.PI / 2;

                // 千鸟风格的不规则偏移
                const zigzagOffset = (Math.random() - 0.5) * totalLength * 0.08 * (1 - posOnLine);

                const x = baseX + Math.cos(perpAngle) * offset + Math.sin(angle) * zigzagOffset;
                const y = baseY + Math.sin(perpAngle) * offset + Math.cos(angle) * zigzagOffset;

                points.push({ x, y });
            }

            points.push({ x: endX, y: endY });
            return points;
        }

        // 生成分支闪电
        generateCombinedBranches(thunder, branchLevel) {
            const points = thunder.points;
            const branchLengthFactor = 0.5;

            // 从主路径上选择一些点作为分支起点
            const branchPoints = [];
            for (let i = 1; i < points.length - 2; i += 2) {
                if (Math.random() < thunder.branchChance) {
                    branchPoints.push(i);
                }
            }

            // 为每个分支点创建分支
            for (const idx of branchPoints) {
                const startPoint = points[idx];
                const endPoint = points[idx + 1];

                // 计算分支方向
                const angle = Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x);
                const branchAngle = angle + (Math.random() - 0.5) * Math.PI / 2;
                const branchLength = Math.sqrt(
                    Math.pow(endPoint.x - startPoint.x, 2) +
                    Math.pow(endPoint.y - startPoint.y, 2)
                ) * branchLengthFactor;

                const branchEndX = startPoint.x + Math.cos(branchAngle) * branchLength;
                const branchEndY = startPoint.y + Math.sin(branchAngle) * branchLength;

                // 创建分支
                const branch = {
                    startX: startPoint.x,
                    startY: startPoint.y,
                    endX: branchEndX,
                    endY: branchEndY,
                    segments: Math.max(3, Math.floor(thunder.segments * 0.5)),
                    alpha: 0.8,
                    color: thunder.color,
                    points: this.generateCombinedLightningPath(startPoint.x, startPoint.y, branchEndX, branchEndY, Math.max(3, Math.floor(thunder.segments * 0.5))),
                    branches: []
                };

                // 递归生成子分支
                if (branchLevel > 1) {
                    this.generateCombinedBranches(branch, branchLevel - 1);
                }

                thunder.branches.push(branch);
            }
        }

        // 创建融合爆炸效果
        createCombinedExplosion(x, y, size, damage) {
            const explosion = {
                x,
                y,
                size,
                maxSize: size * 2,
                alpha: 1,
                fadeSpeed: 0.05 / this.timeScale,
                color: this.explosionColors[Math.floor(Math.random() * this.explosionColors.length)],
                damage
            };

            this.explosions.push(explosion);

            // 创建爆炸粒子
            this.createCombinedExplosionParticles(x, y, size, damage);

            return explosion;
        }

        // 创建融合爆炸粒子
        createCombinedExplosionParticles(x, y, size, damage) {
            // 如果页面不可见或渲染已暂停,不创建新粒子
            if (!isPageVisible || this.isPaused) return;

            // 雷霆风格粒子
            const thunderParticleCount = 20 + Math.floor(Math.random() * 10);
            for (let i = 0; i < thunderParticleCount; i++) {
                const angle = Math.random() * Math.PI * 2;
                const speed = 1 + Math.random() * 3;
                const particle = {
                    x,
                    y,
                    vx: Math.cos(angle) * speed,
                    vy: Math.sin(angle) * speed,
                    size: 1.5 + Math.random() * 2,
                    alpha: 1,
                    fadeSpeed: 0.03 / this.timeScale,
                    color: this.explosionColors[Math.floor(Math.random() * this.explosionColors.length)],
                    type: 'thunder'
                };
                this.particles.push(particle);
            }

            // 千鸟风格粒子
            const chidoriParticleCount = Math.min(100, damage / 2);
            for (let i = 0; i < chidoriParticleCount; i++) {
                const angle = Math.random() * Math.PI * 2;
                const speed = 0.5 + Math.random() * 2;
                const particle = {
                    x,
                    y,
                    vx: Math.cos(angle) * speed,
                    vy: Math.sin(angle) * speed,
                    size: 0.8 + Math.random(),
                    alpha: 1,
                    fadeSpeed: 0.02 / this.timeScale,
                    color: this.lightningColors[Math.floor(Math.random() * this.lightningColors.length)],
                    type: 'chidori'
                };
                this.particles.push(particle);
            }
        }

        // 创建千鸟风格粒子
        createChidoriParticles(x, y, damage) {
            // 如果页面不可见或渲染已暂停,不创建新粒子
            if (!isPageVisible || this.isPaused) return;

            const particleCount = Math.min(150, damage);
            for (let i = 0; i < particleCount; i++) {
                const angle = Math.random() * Math.PI * 2;
                const speed = 1 + Math.random() * 2;
                const size = 0.8 + Math.random();

                this.particles.push({
                    x, y,
                    vx: Math.cos(angle) * speed,
                    vy: Math.sin(angle) * speed,
                    size,
                    alpha: 1,
                    fadeSpeed: 0.02 / this.timeScale,
                    color: this.lightningColors[Math.floor(Math.random() * this.lightningColors.length)],
                    type: 'chidori'
                });
            }
        }

        // 绘制融合闪电
        drawLightning(lightning) {
            if (lightning.alpha <= 0) return;

            const points = lightning.points;

            // 绘制主路径
            this.ctx.beginPath();
            this.ctx.moveTo(points[0].x, points[0].y);
            for (let i = 1; i < points.length; i++) {
                this.ctx.lineTo(points[i].x, points[i].y);
            }

            // 根据闪电强度调整线条粗细
            const baseWidth = lightning.isMain ? // 判断是否为主闪电(从天而降的核心闪电)
                2.5 + Math.min(3, lightning.damage / 150) ://按需求修改 ←←←←←← //主闪电的线条宽度计算:基础值2.5px + 最小化后的伤害比例(伤害/150,最高3px) 基础宽度越大视觉上更粗更明显
                1.5 + Math.min(2, lightning.damage / 300);//按需求修改 ←←←←←←// 普通闪电的线条宽度计算:基础值1.5px + 最小化后的伤害比例(伤害/300,最高2px)

            // 主闪电使用多层渲染增强视觉效果
            if (lightning.isMain) {
                // 外层光晕
                this.ctx.strokeStyle = this.getAlphaColor('#DBEAFE', lightning.alpha * 0.3);
                this.ctx.lineWidth = baseWidth * 2.5;
                this.ctx.stroke();

                // 中层
                this.ctx.strokeStyle = this.getAlphaColor('#93C5FD', lightning.alpha * 0.6);
                this.ctx.lineWidth = baseWidth * 1.5;
                this.ctx.stroke();
            }

            // 内层核心
            this.ctx.strokeStyle = this.getAlphaColor(lightning.color, lightning.alpha);
            this.ctx.lineWidth = baseWidth;
            this.ctx.stroke();

            // 白色高光
            this.ctx.strokeStyle = this.getAlphaColor('#FFFFFF', lightning.alpha * 0.8);
            this.ctx.lineWidth = baseWidth * 0.5;
            this.ctx.stroke();

            // 绘制分支
            for (const branch of lightning.branches) {
                this.drawLightning(branch);
            }
        }

        // 绘制融合爆炸
        drawExplosion(explosion) {
            if (explosion.alpha <= 0) return;

            // 爆炸扩展然后收缩
            if (explosion.size < explosion.maxSize) {
                explosion.size += explosion.maxSize * 0.03 / this.timeScale;
            }

            // 绘制爆炸光圈
            this.ctx.beginPath();
            this.ctx.arc(explosion.x, explosion.y, explosion.size, 0, Math.PI * 2);

            const gradient = this.ctx.createRadialGradient(
                explosion.x, explosion.y, 0,
                explosion.x, explosion.y, explosion.size
            );

            // 爆炸核心使用更亮的颜色
            const coreColor = this.getAlphaColor(
                explosion.color === '#FFFFFF' ? '#DBEAFE' : explosion.color,
                explosion.alpha * 0.9
            );

            gradient.addColorStop(0, coreColor);
            gradient.addColorStop(1, this.getAlphaColor(explosion.color, 0));

            this.ctx.fillStyle = gradient;
            this.ctx.fill();

            // 绘制冲击波
            this.ctx.beginPath();
            this.ctx.arc(explosion.x, explosion.y, explosion.size * 1.2, 0, Math.PI * 2);

            const shockGradient = this.ctx.createRadialGradient(
                explosion.x, explosion.y, explosion.size * 1.1,
                explosion.x, explosion.y, explosion.size * 1.2
            );

            shockGradient.addColorStop(0, this.getAlphaColor('#DBEAFE', explosion.alpha * 0.3));
            shockGradient.addColorStop(1, this.getAlphaColor('#DBEAFE', 0));

            this.ctx.strokeStyle = shockGradient;
            this.ctx.lineWidth = 2;
            this.ctx.stroke();
        }

        // 绘制粒子
        drawParticle(particle) {
            if (particle.alpha <= 0) return;

            this.ctx.beginPath();
            this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);

            // 不同类型的粒子使用不同的绘制方式
            if (particle.type === 'chidori') {
                // 千鸟粒子添加辉光效果
                const gradient = this.ctx.createRadialGradient(
                    particle.x, particle.y, 0,
                    particle.x, particle.y, particle.size * 2
                );

                gradient.addColorStop(0, this.getAlphaColor(particle.color, particle.alpha));
                gradient.addColorStop(1, this.getAlphaColor(particle.color, 0));

                this.ctx.fillStyle = gradient;
            } else {
                this.ctx.fillStyle = this.getAlphaColor(particle.color, particle.alpha);
            }

            this.ctx.fill();
        }

        // 更新闪电
        updateLightning(lightning) {
            lightning.alpha -= lightning.fadeSpeed;

            // 更新分支
            for (let i = lightning.branches.length - 1; i >= 0; i--) {
                const branch = lightning.branches[i];
                this.updateLightning(branch);
                if (branch.alpha <= 0) {
                    lightning.branches.splice(i, 1);
                }
            }
        }

        // 更新爆炸
        updateExplosion(explosion) {
            explosion.alpha -= explosion.fadeSpeed;
        }

        // 更新粒子
        updateParticle(particle) {
            particle.x += particle.vx;
            particle.y += particle.vy;
            particle.alpha -= particle.fadeSpeed;
        }

        // 颜色工具函数 - 添加透明度
        getAlphaColor(color, alpha) {
            // 处理rgb和rgba格式
            if (color.startsWith('rgba')) {
                return color.replace(/rgba\(([^,]+,[^,]+,[^,]+),[^)]+\)/, `rgba($1,${alpha})`);
            } else if (color.startsWith('rgb')) {
                return color.replace(/rgb\(([^)]+)\)/, `rgba($1,${alpha})`);
            } else if (color.startsWith('#')) {
                // 将#RGB或#RGBA转换为rgba
                let r, g, b;
                if (color.length === 4) {
                    r = parseInt(color.charAt(1) + color.charAt(1), 16);
                    g = parseInt(color.charAt(2) + color.charAt(2), 16);
                    b = parseInt(color.charAt(3) + color.charAt(3), 16);
                } else if (color.length === 7) {
                    r = parseInt(color.substring(1, 3), 16);
                    g = parseInt(color.substring(3, 5), 16);
                    b = parseInt(color.substring(5, 7), 16);
                }
                return `rgba(${r},${g},${b},${alpha})`;
            }
            return color;
        }

        // 动画循环
        animate(timestamp) {
            // 如果页面不可见或渲染已暂停,跳过渲染但保持动画循环
            if (!isPageVisible || this.isPaused) {
                this.lastTimestamp = 0;
                requestAnimationFrame(this.animate);
                return;
            }

            // 计算时间增量
            if (!this.lastTimestamp) {
                this.lastTimestamp = timestamp;
            }
            const deltaTime = (timestamp - this.lastTimestamp) / 1000;
            this.lastTimestamp = timestamp;

            // 清除画布
            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

            // 更新和绘制闪电
            for (let i = this.thunders.length - 1; i >= 0; i--) {
                const thunder = this.thunders[i];
                this.updateLightning(thunder);
                this.drawLightning(thunder);

                if (thunder.alpha <= 0 && thunder.branches.length === 0) {
                    this.thunders.splice(i, 1);
                }
            }

            // 更新和绘制爆炸
            for (let i = this.explosions.length - 1; i >= 0; i--) {
                const explosion = this.explosions[i];
                this.updateExplosion(explosion);
                this.drawExplosion(explosion);

                if (explosion.alpha <= 0) {
                    this.explosions.splice(i, 1);
                }
            }

            // 更新和绘制粒子
            for (let i = this.particles.length - 1; i >= 0; i--) {
                const particle = this.particles[i];
                this.updateParticle(particle);
                this.drawParticle(particle);

                if (particle.alpha <= 0) {
                    this.particles.splice(i, 1);
                }
            }

            // 继续动画循环
            requestAnimationFrame(this.animate);
        }
    }

    // 计算元素中心位置
    function center(el) {
        const r = el.getBoundingClientRect();
        return { x: r.left + r.width / 2, y: r.top + r.height / 2 };
    }

    // 创建复合特效实例
    const combinedEffect = new CombinedThunderEffect(canvas);

    // 监听页面可见性变化,控制特效渲染
    if (visibilityChangeEvent && hiddenProp) {
        document.addEventListener(visibilityChangeEvent, () => {
            if (document[hiddenProp]) {
                combinedEffect.setPaused(true);
            } else {
                combinedEffect.setPaused(false);
            }
        });
    }

    // Websocket 劫持
    (function() {
        const desc = Object.getOwnPropertyDescriptor(MessageEvent.prototype, 'data');
        const orig = desc.get;
        desc.get = function() {
            const sock = this.currentTarget;
            const msg = orig.call(this);
            if (sock instanceof WebSocket && sock.url.includes('api.milkywayidle.com/ws')) {
                return handle(msg);
            }
            return msg;
        };
        Object.defineProperty(MessageEvent.prototype, 'data', desc);
    })();

    // 上一帧状态
    const prev = { pMP: [], mHP: [] };
    let autoIdx = 0;
    function handle(message) {
        let obj;
        try { obj = JSON.parse(message); } catch { return message; }
        if (obj.type === 'new_battle') {
            prev.pMP = obj.players.map(p => p.currentManapoints);
            prev.mHP = obj.monsters.map(m => m.currentHitpoints);
            autoIdx = 0;
        } else if (obj.type === 'battle_updated' && prev.mHP.length) {
            const pMap = obj.pMap, mMap = obj.mMap;
            // 检测施法者
            let caster = -1;
            Object.keys(pMap).forEach(i => {
                if (pMap[i].cMP < prev.pMP[i]) caster = +i;
                prev.pMP[i] = pMap[i].cMP;
            });
            const players = document.querySelectorAll('[class*="BattlePanel_playersArea"] [class*="CombatUnit_unit"]');
            const monsters = document.querySelectorAll('[class*="BattlePanel_monstersArea"] [class*="CombatUnit_unit"]');
            const playerCount = players.length;
            Object.keys(mMap).forEach(idx => {
                const i = +idx;
                const oldHP = prev.mHP[i], newHP = mMap[i].cHP;
                if (newHP < oldHP) {
                    const dmg = oldHP - newHP;
                    if (dmg > 0) {
                        const src = caster >= 0 ? caster : autoIdx % playerCount;
                        const fromEl = players[src], toEl = monsters[i];
                        if (fromEl && toEl) {
                            const s = center(fromEl), t = center(toEl);

                            // 根据伤害值计算攻击强度(控制闪电数量、粗细等)
                            // 公式:伤害 / 1000,强度上限为5
                            // 例如:伤害1000对应强度1,伤害5000对应强度5(超过5000伤害强度不再增加)
                            // 可按需更改 👇
                            const intensity = Math.min(5, dmg / 1000);//按需求修改 ←←←←←←


                            // 计算攻击范围(像素)
                            // 基础范围60px,加上最小化后的伤害比例(伤害 / 5),但最多叠加150px
                            // 可按需更改 👇 500伤害可以获得60+100=160的范围像素,伤害超过750到达150px上限
                            const radius = 60 + Math.min(150, dmg / 5);//按需求修改 ←←←←←←

                            // 创建融合特效
                            combinedEffect.createCombinedEffect(t.x, t.y, radius, intensity, dmg);
                        }
                        if (caster < 0) autoIdx++;
                    }
                }
                prev.mHP[i] = newHP;
            });
        }
        return message;
    }

    // 动画循环
    let deltaTime = 0;
    let lastTime = 0;
    function animate(timestamp) {
        deltaTime = (timestamp - lastTime) / 1000;
        lastTime = timestamp;

        requestAnimationFrame(animate);
    }

    animate(0);
})();