// ==UserScript== // @name 宝可梦挂机游戏 - 进化条件显示增强版 // @namespace https://github.com/jinwind1/pokemon-idle // @version 2.0.0 // @description 显示详细进化条件:进化后种族值、属性、地区解锁要求及进化链 // @author 人民当家做主 // @match https://jinwind1.github.io/pokemon-idle/ // @match https://jinwind1.github.io/pokemon-idle/* // @grant GM_addStyle // @run-at document-start // @license MIT // ==/UserScript== (function() { 'use strict'; // 添加样式 GM_addStyle(` .dex-evolution-section { margin-top: 10px; padding: 8px 10px; background: rgba(0, 0, 0, 0.25); border-radius: 8px; font-size: 11px; border-left: 3px solid #f39c12; } .dex-evolution-title { font-weight: bold; color: #f39c12; margin-bottom: 6px; display: flex; align-items: center; gap: 6px; } .dex-evolution-chain { margin-bottom: 6px; font-size: 10px; color: var(--text-secondary); background: rgba(0,0,0,0.2); padding: 4px 6px; border-radius: 4px; } .dex-evolution-item { margin-bottom: 8px; border-bottom: 1px dashed rgba(255,255,255,0.1); padding-bottom: 6px; } .dex-evolution-item:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .evo-target-name { font-weight: bold; color: #2ecc71; } .evo-details { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; margin-left: 12px; } .evo-detail { background: rgba(0,0,0,0.2); padding: 2px 6px; border-radius: 4px; font-size: 10px; } .evo-detail span { color: #f1c40f; } .region-lock { color: #e74c3c; font-size: 10px; } .team-evolution-info { font-size: 9px; color: #f39c12; background: rgba(243, 156, 18, 0.15); border-radius: 4px; padding: 1px 5px; margin-left: 6px; white-space: nowrap; display: inline-block; vertical-align: middle; cursor: help; } `); // 获取宝可梦的种族值总和 function getBaseStatTotal(pokemonId) { const data = POKEMON_DATA[pokemonId]; if (!data) return 0; const bs = data.baseStats; return bs.hp + bs.atk + bs.def + bs.spAtk + bs.spDef + bs.speed; } // 获取宝可梦的属性类型文字 function getTypeNames(pokemonId) { const data = POKEMON_DATA[pokemonId]; if (!data) return ''; return data.types.map(t => TYPE_NAMES[t] || t).join('/'); } // 判断进化目标是否需要解锁地区(跨代进化) function getRegionRequirement(evoId) { if (evoId >= 152 && evoId <= 251) return '城都地区'; if (evoId >= 252 && evoId <= 386) return '丰缘地区'; if (evoId >= 387 && evoId <= 493) return '神奥地区'; if (evoId >= 494 && evoId <= 649) return '合众地区'; if (evoId >= 650 && evoId <= 721) return '卡洛斯地区'; if (evoId >= 722 && evoId <= 809) return '阿罗拉地区'; if (evoId >= 810 && evoId <= 905) return '伽勒尔地区'; if (evoId >= 906 && evoId <= 1025) return '帕底亚地区'; return null; } // 获取进化链(从当前宝可梦开始,一直追溯到最终形态) function getEvolutionChain(pokemonId, maxDepth = 5) { const chain = [{ id: pokemonId, name: POKEMON_DATA[pokemonId]?.name || `#${pokemonId}` }]; let current = pokemonId; for (let i = 0; i < maxDepth; i++) { const data = POKEMON_DATA[current]; if (!data || !data.evolvesTo) break; const evos = Array.isArray(data.evolvesTo) ? data.evolvesTo : [data.evolvesTo]; if (evos.length === 0) break; // 取第一个进化目标(简化显示主链) const next = evos[0]; chain.push({ id: next.id, name: POKEMON_DATA[next.id]?.name || `#${next.id}`, level: next.level }); current = next.id; } return chain; } // 生成进化链文字 function formatEvolutionChain(chain) { if (chain.length <= 1) return '最终形态'; return chain.map((item, idx) => { if (idx === 0) return item.name; return `${item.name} (Lv.${item.level})`; }).join(' → '); } // 获取进化条件HTML(增强版) function getEnhancedEvolutionHtml(pokemonId) { const data = POKEMON_DATA[pokemonId]; if (!data) return ''; const evolvesTo = data.evolvesTo; if (!evolvesTo || (Array.isArray(evolvesTo) && evolvesTo.length === 0)) { // 最终形态,显示进化链回溯 const chain = getEvolutionChain(pokemonId); if (chain.length > 1) { return `
🌱 进化路径
${formatEvolutionChain(chain)}
✨ 最终形态,无法继续进化
`; } return ''; } const evoList = Array.isArray(evolvesTo) ? evolvesTo : [evolvesTo]; let itemsHtml = ''; for (const evo of evoList) { const targetId = evo.id; const targetName = POKEMON_DATA[targetId]?.name || `#${targetId}`; const targetTotal = getBaseStatTotal(targetId); const currentTotal = getBaseStatTotal(pokemonId); const statChange = targetTotal - currentTotal; const statChangeText = statChange > 0 ? `+${statChange}` : `${statChange}`; const targetTypes = getTypeNames(targetId); const currentTypes = getTypeNames(pokemonId); const typeChange = (currentTypes !== targetTypes) ? ` → ${targetTypes}` : ''; const regionReq = getRegionRequirement(targetId); const regionHtml = regionReq ? `
🔒 需要解锁: ${regionReq}
` : ''; itemsHtml += `
➜ Lv.${evo.level} 进化成 ${targetName}
📊 种族值: ${currentTotal} → ${targetTotal} (${statChangeText})
🎭 属性: ${currentTypes}${typeChange}
${regionHtml}
`; } // 显示完整进化链(可选) const chain = getEvolutionChain(pokemonId); const chainHtml = chain.length > 1 ? `
📈 进化链: ${formatEvolutionChain(chain)}
` : ''; return `
🌱 进化条件
${chainHtml} ${itemsHtml}
`; } // 队伍卡片徽章(保持简洁,悬浮显示更多) function getEnhancedTeamBadge(pokemonId) { const data = POKEMON_DATA[pokemonId]; if (!data) return ''; const evolvesTo = data.evolvesTo; if (!evolvesTo || (Array.isArray(evolvesTo) && evolvesTo.length === 0)) return ''; const evoList = Array.isArray(evolvesTo) ? evolvesTo : [evolvesTo]; let minLevel = Infinity; let targetName = ''; for (const evo of evoList) { if (evo.level < minLevel) { minLevel = evo.level; targetName = POKEMON_DATA[evo.id]?.name || `#${evo.id}`; } } if (minLevel === Infinity) return ''; // 悬浮显示更详细信息 const targetTotal = getBaseStatTotal(evoList[0].id); const currentTotal = getBaseStatTotal(pokemonId); const statChange = targetTotal - currentTotal; const tooltip = `Lv.${minLevel} → ${targetName} | 种族值 ${currentTotal} → ${targetTotal} (${statChange>0?'+':''}${statChange})`; return `🌱 Lv.${minLevel}`; } // 劫持图鉴渲染方法 const originalRenderBatch = GameUI.prototype._renderPokedexBatch; if (originalRenderBatch) { GameUI.prototype._renderPokedexBatch = function(grid, count) { originalRenderBatch.call(this, grid, count); const newCards = grid.querySelectorAll('.pokedex-entry:not([data-evo-injected])'); newCards.forEach(card => { const pokemonId = card.dataset.pokemonId; if (pokemonId) { const detailDiv = card.querySelector('.dex-detail'); if (detailDiv) { const evoHtml = getEnhancedEvolutionHtml(parseInt(pokemonId)); if (evoHtml) { detailDiv.insertAdjacentHTML('beforeend', evoHtml); } } } card.setAttribute('data-evo-injected', 'true'); }); }; } else { // 降级:MutationObserver const observer = new MutationObserver(() => { document.querySelectorAll('.pokedex-entry:not([data-evo-injected])').forEach(card => { const pokemonId = card.dataset.pokemonId; if (pokemonId) { const detailDiv = card.querySelector('.dex-detail'); if (detailDiv) { const evoHtml = getEnhancedEvolutionHtml(parseInt(pokemonId)); if (evoHtml) { detailDiv.insertAdjacentHTML('beforeend', evoHtml); } } } card.setAttribute('data-evo-injected', 'true'); }); }); observer.observe(document.getElementById('pokedex-grid'), { childList: true, subtree: true }); } // 劫持队伍渲染 const originalRenderTeam = GameUI.prototype.renderTeam; GameUI.prototype.renderTeam = function() { originalRenderTeam.call(this); const team = this.game.gameState.team; const slots = document.querySelectorAll('.team-slot'); for (let i = 0; i < slots.length && i < team.length; i++) { const pokemonId = team[i]; const badge = getEnhancedTeamBadge(pokemonId); if (!badge) continue; const slotNameDiv = slots[i].querySelector('.slot-name'); if (slotNameDiv && !slotNameDiv.querySelector('.team-evolution-info')) { slotNameDiv.insertAdjacentHTML('beforeend', badge); } } }; // 初始执行 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { setTimeout(() => { if (window.gameUI) { window.gameUI.renderTeam(); document.querySelectorAll('.pokedex-entry').forEach(card => { if (!card.hasAttribute('data-evo-injected')) { const pokemonId = card.dataset.pokemonId; if (pokemonId) { const detailDiv = card.querySelector('.dex-detail'); if (detailDiv) { const evoHtml = getEnhancedEvolutionHtml(parseInt(pokemonId)); if (evoHtml) { detailDiv.insertAdjacentHTML('beforeend', evoHtml); } } } card.setAttribute('data-evo-injected', 'true'); } }); } }, 1000); }); } else { setTimeout(() => { if (window.gameUI) { window.gameUI.renderTeam(); document.querySelectorAll('.pokedex-entry').forEach(card => { if (!card.hasAttribute('data-evo-injected')) { const pokemonId = card.dataset.pokemonId; if (pokemonId) { const detailDiv = card.querySelector('.dex-detail'); if (detailDiv) { const evoHtml = getEnhancedEvolutionHtml(parseInt(pokemonId)); if (evoHtml) { detailDiv.insertAdjacentHTML('beforeend', evoHtml); } } } card.setAttribute('data-evo-injected', 'true'); } }); } }, 1000); } })();