跳转到内容
logo
我的世界XyeBBS论坛3群 进群吹水聊天!众多整合包作者、插件作者、玩家在内哦!不定时发福利,公布重要通知!
...

幻想物语:RE

别卷了!这次,我只想在异世界种田顺便拯救世界!
服务端/客户端剧情养成魔法经营风景RPG
...
Boss伤害占比显示脚本来辣!
#61由shiny_Asuna提交于 12/23/2025, 10:36:29 PM
1个动态

今天写了一个kubejs的伤害占比脚本给我服务器的玩家用:D

这个脚本可以检测稀有度为 传说、神话、boss的怪并且在聊天栏广播所有对其造成伤害的玩家输出的伤害占比~

测试过应该没什么问题了。脚本如下。(如果需要.js文件可以QQ找咱,这里发不了= =,而且好像会有缩进问题)

// 《幻想物语RE》整合包服务器伤害统计脚本(基于kubejs) // 作者:shiny_Asuna 有问题联系:719759587@qq.com // 想要加载此脚本请把这个脚本放在服务端这个路径:kubejs/server_scripts/boss_dmg_brd.js // 测试环境:forge服务端,整合包版本1.0.8b2 测试通过 // 声明: // 本人只开源脚本代码,不对如何使用脚本以及脚本产生的影响负任何责任(不过如果找我提问,附带全套信息我可能能帮你) // 由于Rhino对于const有非常严格的要求所以我使用 var 替代 const(我也想优化,但是没办法,用const老是有已声明报错) // 然后挖砍似乎会连续触发death事件, // 并且entity.uuid 返回的是一个 UUID对象,不是字符串。JavaScript中,两个内容相同的对象 { } !== {} // 所以脚本中使用普通对象而不是Map,否则每次受伤会创建一个新的记录,反正挺抽象的。 //---------------------------【配置区】---------------------------------- var CLEANUP_TICKS = 20 * 60 * 5  // 5分钟清理(对于一个boss的伤害记录只保留 此分钟 数值) var MAX_DISTANCE = 256          // 消息广播范围(同一维度内,距离boss多少格玩家会收到聊天栏消息) // Boss稀有度关键词 var BOSS_RARITY_TYPES = ['boss', 'mythic', 'legendary'] //统计这些稀有度的怪物数值(检测的是怪物的稀有度词条) var MIN_BOSS_HP = 100000 //统计的怪物血量需大于此数值,否则不统计 //--------------------------【脚本主体】--------------------------------- console.info('[BDTracker] Boss伤害统计脚本已加载|written by shiny_Asuna') // 存储Boss伤害记录 var bossDamageRecords = {} var deadBosses = {} // 特殊字符和装饰 var DECORATIONS = {   separator: "══════════════════════════════",   star: "✦",   diamond: "♦",   arrow: "➤",   crown: "♔",   fire: "♨",   sword: "⚔",   heart: "❤",   shield: "⛨",   skull: "☠",   star_filled: "★",   star_empty: "☆",   dot: "•",   line: "|",   corner_tl: "╔",   corner_tr: "╗",   corner_bl: "╚",   corner_br: "╝",   line_h: "═",   line_v: "║",   cross: "╬",   t_right: "╠",   t_left: "╣",   t_down: "╦",   t_up: "╩" } // 颜色定义 var COLORS = {   reset: "§r",   black: "§0",   dark_blue: "§1",   dark_green: "§2",   dark_aqua: "§3",   dark_red: "§4",   dark_purple: "§5",   gold: "§6",   gray: "§7",   dark_gray: "§8",   blue: "§9",   green: "§a",   aqua: "§b",   red: "§c",   light_purple: "§d",   yellow: "§e",   white: "§f",   bold: "§l",   italic: "§o",   underline: "§n",   strikethrough: "§m" } // 稀有度配置 var RARITY_CONFIG = {   'boss': {     name: "首领",     primary_color: COLORS.red + COLORS.bold,      // 红色加粗     secondary_color: COLORS.gold,                 // 金色     accent_color: COLORS.yellow,                  // 黄色     icon: DECORATIONS.crown + " ",                // 王冠     border_color: COLORS.dark_red,                // 深红边框     bar_filled: COLORS.red,                       // 进度条填充色     bar_empty: COLORS.dark_gray                   // 进度条空白色   },   'mythic': {     name: "神话",     primary_color: COLORS.light_purple + COLORS.bold, // 粉色加粗,移除魔法效果     secondary_color: COLORS.dark_purple,          // 紫色     accent_color: COLORS.aqua,                    // 水色     icon: DECORATIONS.star + " ",                 // 星星     border_color: COLORS.dark_purple,             // 紫色边框     bar_filled: COLORS.light_purple,              // 进度条填充色     bar_empty: COLORS.dark_purple                 // 进度条空白色   },   'legendary': {     name: "传说",     primary_color: COLORS.gold + COLORS.bold,     // 金色加粗     secondary_color: COLORS.yellow,               // 亮黄色     accent_color: COLORS.red,                     // 红色     icon: DECORATIONS.fire + " ",                 // 火焰     border_color: COLORS.gold,                    // 金色边框     bar_filled: COLORS.yellow,                    // 进度条填充色     bar_empty: COLORS.gold                        // 进度条空白色   },   'unknown': {     name: "未知",     primary_color: COLORS.white + COLORS.bold,     secondary_color: COLORS.gray,     accent_color: COLORS.aqua,     icon: DECORATIONS.skull + " ",     border_color: COLORS.dark_gray,     bar_filled: COLORS.aqua,     bar_empty: COLORS.dark_gray   } } // 辅助函数:获取UUID字符串 function getUUIDString(uuidObj) {   if (!uuidObj) return ''   if (typeof uuidObj === 'string') return uuidObj   if (uuidObj.toString) {     var str = uuidObj.toString()     if (str && str.length > 0) {       return str     }   }   return String(uuidObj) } // 辅助函数:从NBT中获取稀有度 function getRarityFromNBT(entity) {   try {     if (entity.nbt) {       var nbt = entity.nbt       if (nbt.ForgeCaps && nbt.ForgeCaps['mmorpg:entity_data']) {         var mmorpgData = nbt.ForgeCaps['mmorpg:entity_data']         if (mmorpgData.rarity) {           return mmorpgData.rarity.toLowerCase()         }       }     }         try {       var persistentData = entity.persistentData       if (persistentData) {         if (persistentData.get('rarity')) {           return persistentData.get('rarity').toLowerCase()         }         if (persistentData.get('Rarity')) {           return persistentData.get('Rarity').toLowerCase()         }       }     } catch (e) {}   } catch (e) {     console.error('[BDTracker] 获取NBT时出错:', e)   }   return null } // 辅助函数:检查实体是否为Boss function isBoss(entity) {   if (!entity || !entity.isLiving()) return false     var rarity = getRarityFromNBT(entity)     if (rarity) {     for (var i = 0; i < BOSS_RARITY_TYPES.length; i++) {       if (rarity === BOSS_RARITY_TYPES[i]) {         return true       }     }   }     return false } // 辅助函数:创建边框消息 function createBorderedMessage(title, config, width) {   var lines = []   var border = config.border_color + DECORATIONS.line_h   var topBorder = config.border_color + DECORATIONS.corner_tl +                   border.repeat(width - 2) +                   DECORATIONS.corner_tr   var bottomBorder = config.border_color + DECORATIONS.corner_bl +                      border.repeat(width - 2) +                      DECORATIONS.corner_br   var sideBorder = config.border_color + DECORATIONS.line_v     lines.push(topBorder)     // 标题行   var titleContent = config.icon + config.primary_color + title   var padding = Math.max(0, width - titleContent.length - 4)   var titleLine = sideBorder + " " + titleContent + " ".repeat(padding) + " " + sideBorder   lines.push(titleLine)     // 分隔行   var separatorLine = config.border_color + DECORATIONS.t_right +                       border.repeat(width - 2) +                       DECORATIONS.t_left   lines.push(separatorLine)     return {     header: lines,     footer: [separatorLine, bottomBorder],     sideBorder: sideBorder   } } // 辅助函数:创建进度条 function createProgressBar(percentage, config) {   var barLength = 10   var filledBars = Math.round((percentage / 100) * barLength)   var emptyBars = barLength - filledBars     return config.primary_color + "[" +          config.bar_filled + "▮".repeat(filledBars) +          config.bar_empty + "▯".repeat(emptyBars) +          config.primary_color + "]" } // 监听实体受伤事件 EntityEvents.hurt(event => {   var target = event.entity     if (!isBoss(target)) return   var bossUUID = getUUIDString(target.uuid)   if (!bossUUID || deadBosses[bossUUID]) return     var bossRecord = bossDamageRecords[bossUUID]   if (!bossRecord) {     bossRecord = {       total: 0,       players: {},       lastUpdate: Date.now(),       bossType: target.type.toString(),       bossName: target.getName() ? target.getName().getString() : 'Boss',       rarity: getRarityFromNBT(target) || 'unknown'     }     bossDamageRecords[bossUUID] = bossRecord   }   var attacker = event.source.actual   if (!attacker || !attacker.isPlayer()) return   var playerUUID = getUUIDString(attacker.uuid)   var playerName = attacker.name.getString()     if (!playerUUID || playerUUID === '') return     var amount = event.damage !== undefined ? event.damage : (event.getAmount ? event.getAmount() : 0)   if (isNaN(amount) || amount <= 0) return   var playerRecord = bossRecord.players[playerUUID]   if (!playerRecord) {     playerRecord = {       name: playerName,       damage: 0     }     bossRecord.players[playerUUID] = playerRecord   }     bossRecord.total += amount   playerRecord.damage += amount   bossRecord.lastUpdate = Date.now() }) // 监听实体死亡事件 EntityEvents.death(event => {   var entity = event.entity     if (!isBoss(entity)) return   var bossUUID = getUUIDString(entity.uuid)   var bossRecord = bossDamageRecords[bossUUID]   if (!bossRecord || deadBosses[bossUUID]) return     deadBosses[bossUUID] = true   var bossName = bossRecord.bossName || (entity.getName() ? entity.getName().getString() : 'Boss')   var bossRarity = bossRecord.rarity || getRarityFromNBT(entity) || 'unknown'   var config = RARITY_CONFIG[bossRarity] || RARITY_CONFIG['unknown']     // 构建炫酷的广播消息   var lines = []   var borderWidth = 40  // 增加宽度以容纳更长的内容     // 1. 创建带边框的标题   var borderedMsg = createBorderedMessage(bossName + " - 伤害统计", config, borderWidth)   lines = lines.concat(borderedMsg.header)     // 2. 稀有度信息   var rarityInfo = config.secondary_color + "稀有度: " + config.primary_color + config.name   var rarityPadding = Math.max(0, borderWidth - rarityInfo.length - 4)   var rarityLine = borderedMsg.sideBorder + " " + rarityInfo + " ".repeat(rarityPadding) + " " + borderedMsg.sideBorder   lines.push(rarityLine)     // 3. 伤害统计   var damageArray = []     for (var playerUUID in bossRecord.players) {     if (bossRecord.players.hasOwnProperty(playerUUID)) {       var playerRecord = bossRecord.players[playerUUID]       if (playerRecord.damage > 0) {         damageArray.push({           name: playerRecord.name,           damage: playerRecord.damage,           percentage: 0         })       }     }   }     if (damageArray.length === 0) {     var noDamageLine = borderedMsg.sideBorder + " " +                        config.accent_color + DECORATIONS.dot + " 无有效伤害记录" +                        " ".repeat(borderWidth - 18) + " " + borderedMsg.sideBorder     lines.push(noDamageLine)   } else {     // 计算百分比并排序     for (var i = 0; i < damageArray.length; i++) {       damageArray[i].percentage = ((damageArray[i].damage / bossRecord.total) * 100).toFixed(1)     }         damageArray.sort(function(a, b) {       return b.damage - a.damage     })         // 添加伤害排名     var rankIcons = [DECORATIONS.star_filled + " ", DECORATIONS.star_empty + " ", DECORATIONS.diamond + " "]         for (var i = 0; i < damageArray.length; i++) {       var player = damageArray[i]       var rankIcon = i < 3 ? rankIcons[i] : "  "             // 创建玩家伤害行       var progressBar = createProgressBar(player.percentage, config)       var playerInfo = config.secondary_color + rankIcon +                       config.accent_color + player.name + ": " +                       config.primary_color + player.percentage + "% " +                       progressBar       var playerPadding = Math.max(0, borderWidth - playerInfo.length - 4)       var playerLine = borderedMsg.sideBorder + " " + playerInfo + " ".repeat(playerPadding) + " " + borderedMsg.sideBorder       lines.push(playerLine)             // 显示具体伤害值(缩进显示)       var damageValue = Math.round(player.damage).toLocaleString()       var damageInfo = "     " + config.secondary_color + DECORATIONS.arrow + " 伤害: " +                       config.accent_color + damageValue       var damagePadding = Math.max(0, borderWidth - damageInfo.length - 4)       var damageLine = borderedMsg.sideBorder + damageInfo + " ".repeat(damagePadding) + " " + borderedMsg.sideBorder       lines.push(damageLine)     }         // 4. 分隔线     var separatorLine = borderedMsg.sideBorder + " " +                        config.border_color + DECORATIONS.line_h.repeat(borderWidth - 2) +                        " " + borderedMsg.sideBorder     lines.push(separatorLine)         // 5. 总伤害信息     var totalDamage = Math.round(bossRecord.total).toLocaleString()     var totalLine = borderedMsg.sideBorder + " " +                     config.primary_color + DECORATIONS.sword + " 总伤害: " +                     config.accent_color + totalDamage +                     " ".repeat(borderWidth - 14 - totalDamage.length) + " " + borderedMsg.sideBorder     lines.push(totalLine)         // 6. 参与玩家数量     var playerCountLine = borderedMsg.sideBorder + " " +                           config.primary_color + DECORATIONS.heart + " 参与者: " +                           config.accent_color + damageArray.length + " 名玩家" +                           " ".repeat(borderWidth - 20) + " " + borderedMsg.sideBorder     lines.push(playerCountLine)   }     // 添加底部边框   lines = lines.concat(borderedMsg.footer)     // 控制台输出汇总信息   console.info([BDTracker] ${bossName} (${bossRarity}) 死亡,伤害统计:)   console.info([BDTracker] 总伤害: ${Math.round(bossRecord.total).toLocaleString()})   console.info([BDTracker] 玩家数量: ${damageArray.length})   for (var i = 0; i < damageArray.length; i++) {     var player = damageArray[i]     console.info([BDTracker]  ${player.name}: ${player.percentage}% (${Math.round(player.damage).toLocaleString()}))   }   // 广播给附近玩家   var players = entity.level.players   for (var i = 0; i < players.size(); i++) {     var player = players.get(i)     var dx = player.x - entity.x     var dy = player.y - entity.y     var dz = player.z - entity.z     if (dx * dx + dy * dy + dz * dz <= MAX_DISTANCE * MAX_DISTANCE) {       for (var j = 0; j < lines.length; j++) {         player.tell(lines[j])       }     }   }   delete bossDamageRecords[bossUUID] }) // 定期清理过期记录 ServerEvents.tick(event => {   if (event.server.tickCount % 20 !== 0) return     var now = Date.now()   var cleanupTime = CLEANUP_TICKS * 50     for (var bossUUID in bossDamageRecords) {     if (bossDamageRecords.hasOwnProperty(bossUUID)) {       var record = bossDamageRecords[bossUUID]       if (deadBosses[bossUUID] || (now - record.lastUpdate > cleanupTime)) {         delete bossDamageRecords[bossUUID]         delete deadBosses[bossUUID]       }     }   } })

正在加载内容…
Issue操作
管理员
Issue信息
Issue状态
开启
提交时间12/23/2025
Issue标签
Issue负责人