Widget:测试
<style>
/* ==================== 核心布局与通用样式 ==================== */
.simulator-wrapper { font-family: "Microsoft YaHei", sans-serif; background: #f4f6f9; padding: 20px; border-radius: 8px; color: #333; position: relative; }
.sim-panel { background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 4px 15px rgba(0,0,0,0.05); margin-bottom: 20px; }
.sim-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid #ecf0f1; padding-bottom: 15px; margin-bottom: 20px; }
.sim-header h2 { margin: 0; color: #2c3e50; font-size: 24px; }
.points-display { font-size: 18px; font-weight: bold; color: #27ae60; background: #e8f8f5; padding: 8px 15px; border-radius: 20px; border: 1px solid #a3e4d7;}
.points-display.error { color: #c0392b; background: #fdedec; border-color: #f5b7b1; }
/* 按钮组 */
.btn-toggle-panel { background: #8e44ad; color: white; border: none; padding: 12px 20px; font-size: 16px; font-weight:bold; border-radius: 6px; cursor: pointer; width: 100%; margin-bottom: 20px; transition: 0.2s;}
.btn-toggle-panel:hover { background: #9b59b6; }
.btn-toggle-panel.active { background: #e74c3c; }
.btn-toggle-panel.active:hover { background: #c0392b; }
.btn-add-stage { background: #22a6b3; color: white; border: none; padding: 12px 20px; font-size: 16px; font-weight:bold; border-radius: 6px; cursor: pointer; width: 100%; margin-bottom: 20px; transition: 0.2s;}
.btn-add-stage:hover { background: #0097e6; }
.btn-remove { background: #ff7979; color: white; border: none; padding: 6px 12px; border-radius: 4px; cursor: pointer; }
/* ==================== 天赋区块样式 ==================== */
#talent-container { display: none; animation: fadeIn 0.3s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
.base-settings { display: flex; gap: 20px; margin-bottom: 20px; background: #f8f9fa; padding: 15px; border-radius: 6px; }
.base-settings label { font-weight: bold; color: #34495e; }
.base-settings select { padding: 5px; border-radius: 4px; border: 1px solid #bdc3c7; }
.talent-section { margin-bottom: 20px; border: 1px solid #e0e6ed; border-radius: 6px; overflow: hidden; }
.talent-title { background: #f1f2f6; padding: 10px 15px; font-weight: bold; color: #2f3542; border-bottom: 1px solid #e0e6ed; display: flex; justify-content: space-between; }
.talent-group { padding: 15px; display: flex; flex-wrap: wrap; gap: 12px; }
.talent-group label { display: flex; align-items: center; cursor: pointer; background: #f8f9fa; padding: 6px 12px; border-radius: 4px; border: 1px solid #dcdde1; transition: all 0.2s; user-select: none; }
.talent-group label:hover { border-color: #3498db; background: #ebf5fb; }
.talent-group input[type="checkbox"]:checked + span { font-weight: bold; color: #2980b9; }
.warning-text { color: #e74c3c; font-size: 13px; display: none; font-weight: normal; }
/* ==================== 悟道灵树面板 ==================== */
#wudao-container { display: none; padding: 15px; margin-bottom: 20px; animation: fadeIn 0.3s; }
.dao-row { display: grid; grid-template-columns: 80px repeat(5, 1fr); gap: 10px; margin-bottom: 12px; align-items: center; padding: 8px; border-radius: 6px; background: #fdfdfd; border: 1px solid #f1f2f6; transition: background 0.2s; }
.dao-row:hover { background: #f8f9fa; }
.dao-title { font-weight: bold; font-size: 16px; text-align: center; text-shadow: 0 1px 2px rgba(0,0,0,0.1); }
.dao-col { display: flex; flex-wrap: wrap; gap: 6px; padding-left: 10px; border-left: 2px dashed #ecf0f1; min-height: 32px; align-items: center;}
.dao-node { background: #fff; border: 1px solid #bdc3c7; color: #7f8c8d; padding: 4px 10px; border-radius: 15px; font-size: 13px; cursor: pointer; user-select: none; transition: all 0.2s; font-weight: bold; }
.dao-node:hover:not(.locked) { border-color: var(--theme-color); color: var(--theme-color); background: #fdfdfd; box-shadow: 0 2px 5px rgba(0,0,0,0.05); }
.dao-node.active { background: var(--theme-color); color: white; border-color: var(--theme-color); box-shadow: 0 2px 6px rgba(0,0,0,0.15); }
.dao-node.locked { opacity: 0.35; cursor: not-allowed; filter: grayscale(100%); }
.dao-node.symbiotic { border-style: dashed; border-width: 2px; }
/* ==================== 境界板块与插槽网格 ==================== */
.stage-block { background: #fff; border: 2px solid #dff9fb; border-radius: 8px; margin-bottom: 20px; padding: 20px; box-shadow: 0 4px 10px rgba(0,0,0,0.03); transition: all 0.3s; }
.stage-block:hover { border-color: #c7ecee; box-shadow: 0 6px 15px rgba(0,0,0,0.08); }
.stage-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 2px dashed #ecf0f1; padding-bottom: 10px; margin-bottom: 15px; }
.stage-header select { font-size: 18px; font-weight: bold; padding: 6px; color: #130f40; border: 1px solid #badc58; border-radius: 4px; background: #f9ca24; color: #fff;}
.stage-header select option { background: #fff; color: #333; }
.milestone-box { background: #e1f5fe; border: 1px solid #81d4fa; padding: 12px 15px; border-radius: 6px; margin-bottom: 15px; display: flex; gap: 20px; align-items: center; }
.milestone-box select { padding: 5px; border-radius: 4px; border: 1px solid #b3e5fc; font-weight: bold; color: #0277bd; }
.slots-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 25px; }
.slot-group h4 { margin: 0 0 12px 0; color: #30336b; border-left: 4px solid #686de0; padding-left: 10px; background: #f1f2f6; line-height: 30px;}
.slot-item { margin-bottom: 10px; display: flex; align-items: center; gap: 10px; background: #fafafa; padding: 6px; border-radius: 4px; border: 1px solid #f1f2f6;}
.slot-item span.label-title { width: 45px; font-weight: bold; color: #535c68; font-size: 14px; text-align: right;}
.slot-item select.equip-select, .slot-item select.level-select { padding: 6px; border: 1px solid #dcdde1; border-radius: 4px; outline: none; background: #fff;}
.level-select { flex: none !important; width: 70px; }
/* ★★★ 新版视觉化槽位 (Visual Slots) ★★★ */
.skill-slot-container { flex: 1; position: relative; }
.visual-slot { display: flex; align-items: center; background: #fff; border: 1px solid #bdc3c7; border-radius: 6px; padding: 4px 8px; cursor: pointer; min-height: 34px; box-sizing: border-box; transition: all 0.2s; }
.visual-slot:hover { border-color: #3498db; box-shadow: 0 0 5px rgba(52,152,219,0.3); }
.visual-slot.empty { color: #3498db; justify-content: center; border-style: dashed; font-weight: bold; }
.slot-icon { width: 24px; height: 24px; border-radius: 4px; margin-right: 8px; object-fit: cover; background: #ecf0f1; display: inline-block; }
.slot-name { font-weight: bold; color: #2c3e50; font-size: 14px; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot-clear { margin-left: auto; color: #e74c3c; padding: 0 5px; font-weight: bold; font-size: 16px; opacity: 0.6; display: none; }
.visual-slot:hover .slot-clear { display: block; opacity: 1; }
/* ★★★ 智能拾取器弹窗 (Picker Modal) ★★★ */
.picker-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.6); z-index: 9999; display: none; justify-content: center; align-items: center; animation: fadeIn 0.2s; }
.picker-modal { background: #fff; width: 90%; max-width: 650px; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); display: flex; flex-direction: column; max-height: 85vh; overflow: hidden; }
.picker-header { display: flex; justify-content: space-between; align-items: center; padding: 15px 20px; background: #2c3e50; color: #fff; }
.picker-header h3 { margin: 0; font-size: 18px; color: #ffffff !important; }
.close-modal-btn { background: none; border: none; color: #fff; font-size: 24px; cursor: pointer; transition: 0.2s; }
.close-modal-btn:hover { color: #e74c3c; }
.picker-body { padding: 20px; overflow-y: auto; background: #f4f6f9; }
/* 筛选区 */
.search-box { width: 100%; padding: 10px 15px; border: 2px solid #bdc3c7; border-radius: 20px; font-size: 15px; margin-bottom: 15px; box-sizing: border-box; outline: none; transition: 0.2s; }
.search-box:focus { border-color: #3498db; }
.filter-row { margin-bottom: 15px; }
.filter-label { font-weight: bold; color: #34495e; margin-bottom: 8px; font-size: 14px; display: block; border-left: 3px solid #e67e22; padding-left: 8px; }
.filter-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.filter-tag { padding: 4px 12px; background: #fff; border: 1px solid #dcdde1; border-radius: 15px; font-size: 13px; cursor: pointer; color: #7f8c8d; transition: all 0.2s; user-select: none; }
.filter-tag:hover { border-color: #3498db; color: #3498db; }
.filter-tag.active { background: #3498db; color: #fff; border-color: #3498db; }
/* 结果网格 */
.picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; margin-top: 10px; }
.skill-card { background: #fff; border: 1px solid #e0e6ed; border-radius: 6px; padding: 10px; display: flex; flex-direction: column; align-items: center; cursor: pointer; transition: all 0.2s; }
.skill-card:hover { transform: translateY(-3px); box-shadow: 0 4px 10px rgba(0,0,0,0.1); border-color: #3498db; }
.skill-card img { width: 48px; height: 48px; border-radius: 8px; margin-bottom: 8px; background: #ecf0f1; object-fit: cover;}
.skill-card .s-name { font-weight: bold; font-size: 14px; text-align: center; margin-bottom: 4px; color: #2c3e50; }
.skill-card .s-rank { font-size: 12px; color: #fff; background: #f39c12; padding: 2px 6px; border-radius: 10px; }
.skill-card .s-rank.天阶 { background: #e74c3c; }
.skill-card .s-rank.地阶 { background: #9b59b6; }
.skill-card .s-rank.人阶 { background: #2ecc71; }
.loading-text { text-align: center; color: #7f8c8d; padding: 20px; font-weight: bold; }
</style>
✨ 觅长生流派构筑生成器
<button id="btn-toggle-talent" class="btn-toggle-panel">➕ 添加开局天赋与造化要求 (可选)</button>
开局参数设定
<label><input type="checkbox" class="talent-cb bg-cb" data-cost="2">修真家族 (2)</label><label><input type="checkbox" class="talent-cb bg-cb" data-cost="2">书香门第 (2)</label><label><input type="checkbox" class="talent-cb bg-cb" data-cost="1">魂穿异世 (1)</label><label><input type="checkbox" class="talent-cb bg-cb" data-cost="1">练武世家 (1)</label><label><input type="checkbox" class="talent-cb bg-cb" data-cost="1">商贾富豪 (1)</label><label><input type="checkbox" class="talent-cb bg-cb" data-cost="0">普通农户 (0)</label><label><input type="checkbox" class="talent-cb bg-cb" data-cost="-1">流浪孤儿 (-1)</label>
<label style="background: transparent; border: none; padding: 0;">
<select id="root-level" style="padding: 6px; font-weight: bold;"><option value="14" data-count="1">天灵根 (14点)</option><option value="10" data-count="2">双灵根 (10点)</option><option value="6" data-count="3">三灵根 (6点)</option><option value="2" data-count="4">四灵根 (2点)</option><option value="0" data-count="5">伪灵根 (0点)</option></select>
</label>
<label><input type="checkbox" class="elem-cb" value="金">金</label><label><input type="checkbox" class="elem-cb" value="木">木</label><label><input type="checkbox" class="elem-cb" value="水">水</label><label><input type="checkbox" class="elem-cb" value="火">火</label><label><input type="checkbox" class="elem-cb" value="土">土</label>
<label><input type="checkbox" class="talent-cb" data-cost="16">转世仙人 (16)</label><label><input type="checkbox" class="talent-cb" data-cost="8">五气朝元 (8)</label><label><input type="checkbox" class="talent-cb" data-cost="6">龙族血脉 (6)</label><label><input type="checkbox" class="talent-cb" data-cost="6">天生异瞳 (6)</label><label><input type="checkbox" class="talent-cb" data-cost="6">异族血脉 (6)</label><label><input type="checkbox" class="talent-cb" data-cost="6">天道福泽 (6)</label><label><input type="checkbox" class="talent-cb" data-cost="5">神魔血脉 (5)</label><label><input type="checkbox" class="talent-cb" data-cost="4">绝阴毒体 (4)</label><label><input type="checkbox" class="talent-cb mutex-cb" data-mutex="daoti" data-cost="3">先天道体 (3)</label><label><input type="checkbox" class="talent-cb" data-cost="1">乙木灵体 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">水灵之体 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">离火道体 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">戊土之体 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">庚金之体 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="0">普通凡人 (0)</label><label><input type="checkbox" class="talent-cb mutex-cb" data-mutex="daoti" data-cost="-3">玄阴绝脉 (-3)</label><label><input type="checkbox" class="talent-cb" data-cost="-5">羸弱多病 (-5)</label><label><input type="checkbox" class="talent-cb" data-cost="-8">先天异脉 (-8)</label>
<label><input type="checkbox" class="talent-cb mutex-cb" data-mutex="xinzhi" data-cost="4">过目不忘 (4)</label><label><input type="checkbox" class="talent-cb" data-cost="2">星辰泪 (2)</label><label><input type="checkbox" class="talent-cb" data-cost="2">神秘绿瓶 (2)</label><label><input type="checkbox" class="talent-cb" data-cost="1">修身养性 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">道心坚定 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">神奇温泉 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="0">放情丘壑 (0)</label><label><input type="checkbox" class="talent-cb" data-cost="-1">先天残疾 (-1)</label><label><input type="checkbox" class="talent-cb mutex-cb" data-mutex="xinzhi" data-cost="-1">心智有损 (-1)</label><label><input type="checkbox" class="talent-cb" data-cost="-3">大病一场 (-3)</label> <label><input type="checkbox" class="talent-cb" data-cost="4">讲价技巧 (4)</label><label><input type="checkbox" class="talent-cb" data-cost="3">初窥门径 (3)</label><label><input type="checkbox" class="talent-cb" data-cost="2">神秘贝壳 (2)</label><label><input type="checkbox" class="talent-cb" data-cost="2">先天武者 (2)</label><label><input type="checkbox" class="talent-cb" data-cost="2">命犯桃花 (2)</label><label><input type="checkbox" class="talent-cb" data-cost="1">轻功高手 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">药堂学徒 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">后山洞窟 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="1">坠崖奇遇 (1)</label><label><input type="checkbox" class="talent-cb" data-cost="-1">惨遭退婚 (-1)</label>
<button id="btn-toggle-wudao" class="btn-toggle-panel" style="background:#e67e22; margin-bottom:0;">➕ 展开全局悟道加点图 (0 / 108 点)</button>
<button id="add-stage-btn" class="btn-add-stage">➕ 添加全新境界阶段 (记录全流程配置请点击)</button>
📤 流派分享与存档中心
将当前的完美构筑生成“流派码”发给朋友,或粘贴别人的代码一键读取。
<textarea id="build-code-input" rows="4" style="width: 100%; box-sizing: border-box; padding: 10px; border-radius: 4px; border: 1px solid #bdc3c7; font-family: monospace; resize: vertical; margin-bottom:15px;" placeholder="在此粘贴流派分享码..."></textarea>
<button id="btn-export-code" style="background: #3498db; color: #fff; border: none; padding: 12px 20px; border-radius: 4px; cursor: pointer; font-weight: bold; flex: 1; font-size: 16px;">⬇️ 生成并复制分享码</button>
<button id="btn-import-code" style="background: #2ecc71; color: #fff; border: none; padding: 12px 20px; border-radius: 4px; cursor: pointer; font-weight: bold; flex: 1; font-size: 16px;">⬆️ 一键读取并导入构筑</button>
<button id="btn-generate-image" style="background: #9b59b6; color: #fff; border: none; padding: 12px 20px; border-radius: 4px; cursor: pointer; font-weight: bold; flex: 1; font-size: 16px;">📸 生成精美长图分享</button>
<template id="stage-template">
<select class="stage-weight-select">
<option value="99">🎓 毕业构筑 (最终成型)</option>
<option value="10">炼气期</option><option value="20">筑基期</option><option value="30">金丹期</option><option value="40">元婴期</option><option value="50">化神期</option>
</select>
<button class="btn-remove">❌ 删除本阶段</button>
🕮 功法配置 (1主 + 4辅 + 1遁)
⚔️ 装备炼制反推 (选择效果)
🔨 炼器配方与释义:
🔮 神通配置 (最多10槽)
📌 学习前置要求自动汇总:
- 添加功法/神通后自动计算...
</template>
<script> window.WikiData = { methods: {}, spells: {}, loaded: false, scriptPath: '/mcs' }; window.WIKI_STAGE_WEIGHT = { "炼气期": 10, "筑基期": 20, "金丹期": 30, "元婴期": 40, "化神期": 50 }; window.WIKI_DAO_WEIGHT = { "初窥门径": 1, "略有小成": 2, "融会贯通": 3, "道之真境": 4, "大道已成": 5 };
const FILTER_RANKS =['人阶下', '人阶中', '人阶上', '地阶下', '地阶中', '地阶上', '天阶下', '天阶中', '天阶上']; const FILTER_ELEMENTS_SPELL =['金', '木', '水', '火', '土', '剑', '神', '气', '阵法', '隐匿']; const FILTER_ELEMENTS_METHOD =['金', '木', '水', '火', '土', '气', '神', '剑', '体', '遁术'];
var AFFIX_DICT = {
"驭": { cost: 60, desc: "本回合该属性技能伤害+1" }, "振": { cost: 5, desc: "下一次该属性技能伤害+1,触发后移除所有" }, "御": { cost: 10, desc: "本回合受到的该系伤害-1" },
"避金": { cost: 60, desc: "每次受到伤害时,移除自身【易伤】*1" }, "避水": { cost: 60, desc: "每次使用技能时,移除自身【霜冻】*1" }, "避木": { cost: 60, desc: "每次使用技能时,移除自身【缠绕】*1" },
"避火": { cost: 60, desc: "回合结束时,移除自身【灼烧】*12" }, "避毒": { cost: 60, desc: "回合开始时,移除自身【中毒】*12" },
"尘": { cost: 5, desc: "化尘教指示物" }, "沙": { cost: 5, desc: "化尘教指示物" }, "护罩": { cost: 5, desc: "抵挡1点伤害,不会主动移除" },
"吸收": { cost: 180, desc: "回合开始时吸收1点对应灵气" }, "权重": { cost: 5, desc: "对应灵根+1" }, "易伤": { cost: 80, desc: "本回合受到的技能伤害+1" },
"流血": { cost: 100, desc: "回合结束时,受到已损失生命值1%的伤害" }, "蓄势": { cost: 3, desc: "每受到1点伤害移除1层,回合开始造成层数对应的剑系伤害" },
"疗": { cost: 25, desc: "回合结束时,恢复1点生命值。触发一次减少一层" }, "霜冻": { cost: 40, desc: "技能造成的基础伤害-1,每使用一次技能移除一层" },
"恢复生命": { cost: 5, desc: "恢复1点生命值" }, "缠绕": { cost: 30, desc: "本回合每使用技能一次受到1点伤害" }, "中毒": { cost: 30, desc: "回合结束时受到1点伤害,触发减层" },
"灼烧": { cost: 30, desc: "回合开始时受到1点伤害,触发减层" }, "焰": { cost: 40, desc: "本回合造成的火系技能伤害+1" }, "减伤": { cost: 25, desc: "本回合受到的技能伤害-1" },
"化焰": { cost: 40, desc: "受到技能伤害时反弹1点火伤。使用非火技能清空" }, "破体": { cost: 180, desc: "受到的治疗效果减半" },
"缚足": { cost: 30, desc: "遁速-1" }, "速": { cost: 30, desc: "遁速+1" }, "剑气": { cost: 30, desc: "回合结束时,对敌方造成1点剑系伤害" },
"反伤": { cost: 30, desc: "本回合受到技能伤害时,反弹1点伤害" }, "神殇": { cost: 60, desc: "【神识】-1" }, "凝神": { cost: 60, desc: "【神识】+1" }
}; var EQUIP_TYPES =["剑", "钟", "环", "针", "匣", "法袍", "甲胄", "珠", "令", "印"]; var TIAN_YANG = {
"金": "造成金属性伤害|吸收金灵气|获得【驭金】|造成金属性多段伤害|获得【振金】|战斗开始时增加金属性权重|回合结束获得【蓄势】|回合开始获得【避金】|回合开始敌方获得【易伤】|回合开始吸收金灵气", "水": "造成水属性伤害|吸收水灵气|获得【驭水】|造成水属性多段伤害|获得【振水】|战斗开始时增加水属性权重|回合结束获得【疗】|回合开始获得【疗】|回合开始敌方获得【霜冻】|回合开始吸收水灵气", "木": "造成木属性伤害|吸收木灵气|获得【驭木】|造成木属性多段伤害|获得【振木】|战斗开始时增加木属性权重|回合结束恢复生命|回合开始获得【避毒】|回合开始敌方获得【中毒】|回合开始吸收木灵气", "火": "造成火属性伤害|吸收火灵气|获得【驭火】|造成火属性多段伤害|获得【振火】|战斗开始时增加火属性权重|回合结束获得【化焰】|回合开始获得【化焰】|回合开始敌方获得【灼烧】|回合开始吸收火灵气", "土": "造成土属性伤害|吸收土灵气|获得【驭土】|造成土属性多段伤害|获得【振土】|战斗开始时增加土属性权重|回合结束获得【减伤】|回合开始获得【尘】|回合开始敌方获得【沙】|回合开始吸收土灵气", "混元": "造成混元属性伤害|吸收随机灵气|获得【驭气】|造成混元属性多段伤害|获得【振气】|回合结束获得【护罩】|回合结束获得【护罩】|回合开始获得【护罩】|回合开始敌方获得【易伤】|回合开始随机吸收灵气", "剑": "造成剑属性伤害|获得【剑气】|获得【驭剑】|造成剑属性多段伤害|获得【振剑】|回合结束获得【反伤】|回合结束获得【护罩】|回合开始获得【剑气】|回合开始敌方获得【易伤】|回合开始随机吸收灵气", "神念": "造成神属性伤害|获得【凝神】|获得【驭神】|造成神属性多段伤害|获得【振神】|回合结束获得【凝神】|回合结束获得【凝神】|回合开始获得【凝神】|回合开始敌方获得【神殇】|回合开始随机吸收灵气"
}; var DI_YIN = {
"金": "敌方获得【易伤】|获得【御木】|敌方获得【易伤】|敌方获得【流血】|获得【蓄势】|获得【御木】|回合结束获得【蓄势】|回合开始获得【避金】|回合开始敌方获得【易伤】|回合开始获得【蓄势】", "水": "敌方获得【霜冻】|获得【御火】|获得【疗】|敌方获得【霜冻】|获得【疗】|获得【御火】|回合结束获得【疗】|回合开始获得【避水】|回合开始敌方获得【霜冻】|回合开始获得【疗】", "木": "敌方获得【缠绕】|获得【御土】|敌方获得【中毒】|敌方获得【中毒】|恢复生命|获得【御土】|回合结束恢复生命|回合开始获得【避木】|回合开始敌方获得【缠绕】|回合开始恢复生命", "火": "敌方获得【灼烧】|获得【御金】|敌方获得【灼烧】|获得【焰】|获得【化焰】|获得【御金】|回合结束获得【化焰】|回合开始获得【避火】|回合开始敌方获得【灼烧】|回合开始获得【化焰】", "土": "敌方获得【破体】|获得【御水】|获得【尘】|敌方获得【沙】|获得【减伤】|获得【御水】|回合结束获得【减伤】|回合开始获得【尘】|回合开始敌方获得【沙】|回合开始获得【尘】", "混元": "敌方获得【易伤】|吸收随机灵气|获得【护罩】|敌方获得【缚足】|获得【护罩】|回合结束获得【速】|回合结束获得【速】|回合开始获得【护罩】|回合开始敌方获得【易伤】|回合开始获得【护罩】", "剑": "获得【剑气】|获得【护罩】|获得【护罩】|获得【护罩】|获得【剑气】|回合结束获得【反伤】|回合结束获得【护罩】|回合开始获得【剑气】|回合开始敌方获得【易伤】|回合开始获得【剑气】", "神念": "敌方获得【神殇】|获得【凝神】|获得【凝神】|敌方获得【神殇】|获得【凝神】|获得【凝神】|获得【凝神】|回合开始获得【凝神】|回合开始敌方获得【神殇】|回合开始获得【凝神】"
}; var FORGE_DB = { weapon: new Set(), armor: new Set(), trinket: new Set() }; function initForgeDB() {[TIAN_YANG, DI_YIN].forEach(function(matrix) {
for (var elem in matrix) {
var effects = matrix[elem].split('|');
effects.forEach(function(eff, idx) {
if (idx <= 4) FORGE_DB.weapon.add(eff); else if (idx <= 6) FORGE_DB.armor.add(eff); else FORGE_DB.trinket.add(eff);
});
}
});
} initForgeDB();
var MAX_WUDAO_POINTS = 108; var currentWudaoPoints = 0; window.activeDaoNodes = {}; var DAO_CONFIG = {
"金大道": { color: "#f39c12", cols: [["御金"],["蓄势","强金","冲穴"],["生金","御体","五行"],["坚毅","相生(金)","锻金"], ["通金"] ] },
"木大道": { color: "#27ae60", cols: [ ["御木"],["寄生","强木","封喉","火毒"],["生木","自愈","五行"],["盘根","相生(木)","噬心"],["通木"] ] },
"水大道": { color: "#2980b9", cols:[["御水"],["止水","强水","冰冻"],["生水","自愈","五行"],["惊涛","相生(水)","凝脉"], ["通水"] ] },
"火大道": { color: "#c0392b", cols: [ ["御火"],["浴火","强火","吞焰","火毒"],["生火","五行"],["炙火","相生(火)","化焰"],["通火"] ] },
"土大道": { color: "#d35400", cols:[ ["御土"],["引力","强土","归尘"],["生土","御体","五行"],["重岩","相生(土)","凝沙"],["通土"] ] },
"神大道": { color: "#9b59b6", cols: [["凝神"],["心听","闭气"], ["止符"],["观气","敛息","乱魂"], ["心斋"] ] },
"体大道": { color: "#8b0000", cols: [["活血","洗髓"],["炼筋","炼骨","轻身"],["锻体","化劲"],["淬体","冰肌","幻身"],["霸体"] ] },
"剑大道": { color: "#7f8c8d", cols: [["通明"],["剑气","轻剑","重剑"],["入微","护主"],["偏锋","快剑","慢剑"],["斩天"] ] },
"气大道": { color: "#16a085", cols: [["走穴","洗髓"],["易脉","集气"],["储海","充盈","回元","化劲"],["抱朴","引气","静气"],["归一"] ] },
"阵大道": { color: "#2c3e50", cols: [["奇门"],["八卦"],["四象","聚灵"],["两仪","集中"],["太极"] ] },
"丹大道": { color: "#2ecc71", cols: [ ["识药"],["剔毒","假丹"],["控火","抗毒","鉴草"],["耐药"],["丹圣"] ] },
"器大道": { color: "#cd6155", cols: [["朱雀","白虎"],["青龙","玄武","相合"],["增速"], ["控器"],["化灵"] ] }
}; var NODE_DICT = { "洗髓": { cost: 1, type: "symbiotic" }, "化劲": { cost: 4, type: "symbiotic" }, "御体": { cost: 4, type: "symbiotic" }, "自愈": { cost: 4, type: "symbiotic" }, "火毒": { cost: 2, type: "symbiotic" }, "五行": { cost: 4, type: "symbiotic" } };
function fetchWikiData() {
window.WikiData.scriptPath = (typeof mw !== 'undefined' && mw.config) ? mw.config.get('wgScriptPath') : '/mcs';
var methodUrl = window.WikiData.scriptPath + '/api.php?action=ask&format=json&query=' + encodeURIComponent('|?第一层境界要求|?第二层境界要求|?第三层境界要求|?第四层境界要求|?第五层境界要求|?领悟条件|?属性|?品级|?图片ID|limit=500');
fetch(methodUrl).then(function(res){ return res.text(); }).then(function(text){
try {
var data = JSON.parse(text);
if (data && data.query && data.query.results) {
for (var name in data.query.results) {
var item = data.query.results[name].printouts;
var elems =[];
if(item['属性']) elems = elems.concat(item['属性']);
if(item['属性1']) elems = elems.concat(item['属性1']);
if(item['属性2']) elems = elems.concat(item['属性2']);
window.WikiData.methods[name] = {
name: name,
reqs: [
item['第一层境界要求']?.[0]||'炼气期',
item['第二层境界要求']?.[0]||item['第一层境界要求']?.[0]||'炼气期',
item['第三层境界要求']?.[0]||item['第二层境界要求']?.[0]||'炼气期',
item['第四层境界要求']?.[0]||item['第三层境界要求']?.[0]||'炼气期',
item['第五层境界要求']?.[0]||item['第四层境界要求']?.[0]||'炼气期'
],
condition: item['领悟条件']?.[0] || '无',
rank: item['品级']?.[0] || '未知',
imgId: item['图片ID']?.[0] || ,
elements: elems
};
}
}
} catch(e) {}
});
var spellUrl = window.WikiData.scriptPath + '/api.php?action=ask&format=json&query=' + encodeURIComponent('|?领悟条件|?属性|?属性1|?属性2|?品级|?图片ID|limit=500');
fetch(spellUrl).then(function(res){ return res.text(); }).then(function(text){
try {
var data = JSON.parse(text);
if (data && data.query && data.query.results) {
for (var name in data.query.results) {
var item = data.query.results[name].printouts;
var elems = [];
if(item['属性']) elems = elems.concat(item['属性']);
if(item['属性1']) elems = elems.concat(item['属性1']);
if(item['属性2']) elems = elems.concat(item['属性2']);
window.WikiData.spells[name] = {
name: name,
condition: item['领悟条件']?.[0] || '无',
rank: item['品级']?.[0] || '未知',
imgId: item['图片ID']?.[0] || ,
elements: elems
};
}
window.WikiData.loaded = true;
if(document.getElementById('picker-grid')) document.getElementById('picker-grid').innerHTML = ;
}
} catch(e) {}
});
}
function getImgUrl(imgId) {
if (!imgId) return ""; return window.WikiData.scriptPath + "/Special:FilePath/" + imgId + ".png";
}
let currentEditingSlot = null; let currentFilters = { search: , ranks: [], elements:[] };
function initFilters() {
const rDiv = document.getElementById('filter-ranks');
rDiv.innerHTML = ;
FILTER_RANKS.forEach(r => rDiv.innerHTML += `
`);
document.getElementById('picker-search').addEventListener('input', function(e) {
currentFilters.search = e.target.value.trim().toLowerCase();
renderPickerGrid();
});
document.querySelectorAll('#filter-ranks .filter-tag').forEach(el => {
el.addEventListener('click', function() {
this.classList.toggle('active');
let val = this.innerText;
if (currentFilters.ranks.includes(val)) currentFilters.ranks = currentFilters.ranks.filter(v => v !== val);
else currentFilters.ranks.push(val);
renderPickerGrid();
});
});
}
function bindElementFilters() {
document.querySelectorAll('#filter-elements .filter-tag').forEach(el => {
el.addEventListener('click', function() {
this.classList.toggle('active');
let val = this.innerText;
if (currentFilters.elements.includes(val)) currentFilters.elements = currentFilters.elements.filter(v => v !== val);
else currentFilters.elements.push(val);
renderPickerGrid();
});
});
}
window.openPicker = function(slotEl) {
if (!window.WikiData.loaded) return alert("数据正在加载中,请稍候...");
currentEditingSlot = slotEl;
let type = slotEl.dataset.type;
let isMovement = slotEl.dataset.subtype === 'movement';
document.getElementById('picker-title').innerText = type === 'method' ? (isMovement ? "专属槽位:选择遁术" : "选择主修 / 辅修功法") : "配置神通槽位";
let eDiv = document.getElementById('filter-elements');
eDiv.innerHTML = ;
let targetElems = type === 'method' ? FILTER_ELEMENTS_METHOD : FILTER_ELEMENTS_SPELL;
targetElems.forEach(e => eDiv.innerHTML += `
`);
bindElementFilters();
currentFilters = { search: , ranks:[], elements:[] };
document.getElementById('picker-search').value = ;
document.querySelectorAll('.filter-tag').forEach(t => t.classList.remove('active'));
document.getElementById('skill-picker-modal').style.display = 'flex';
renderPickerGrid();
};
window.closePicker = function() {
document.getElementById('skill-picker-modal').style.display = 'none';
currentEditingSlot = null;
};
function renderPickerGrid() {
if (!currentEditingSlot) return;
let type = currentEditingSlot.dataset.type;
let isMovement = currentEditingSlot.dataset.subtype === 'movement';
let db = type === 'method' ? window.WikiData.methods : window.WikiData.spells;
let grid = document.getElementById('picker-grid');
grid.innerHTML = ;
for (let name in db) {
let item = db[name];
if (isMovement && !item.elements.includes('遁术')) continue;
if (currentFilters.search && name.toLowerCase().indexOf(currentFilters.search) === -1) continue;
if (currentFilters.ranks.length > 0 && !currentFilters.ranks.includes(item.rank)) continue;
if (currentFilters.elements.length > 0 && !currentFilters.elements.some(e => item.elements.includes(e))) continue;
let rankClass = "s-rank";
if(item.rank.includes('天阶')) rankClass += " 天阶";
if(item.rank.includes('地阶')) rankClass += " 地阶";
if(item.rank.includes('人阶')) rankClass += " 人阶";
let imgSrc = getImgUrl(item.imgId);
let card = document.createElement('div');
card.className = "skill-card";
card.innerHTML = `<img src="${imgSrc}" onerror="this.style.display='none'">
`;
card.onclick = function() {
let block = currentEditingSlot.closest('.stage-block');
let allSameTypeInputs = block.querySelectorAll('.' + type + '-select');
let isDuplicate = false;
allSameTypeInputs.forEach(input => {
if (input !== currentEditingSlot.parentElement.querySelector('.hidden-val') && input.value === name) {
isDuplicate = true;
}
});
if (isDuplicate) {
alert(`⚠️ 不能重复选择!当前阶段已经装备了【${name}】!`);
return;
}
let hiddenInput = currentEditingSlot.parentElement.querySelector('.hidden-val');
hiddenInput.value = name;
updateVisualSlot(currentEditingSlot, name, item);
hiddenInput.dispatchEvent(new Event('change', {bubbles: true}));
closePicker();
};
grid.appendChild(card);
}
}
function updateVisualSlot(slotEl, name, itemData) {
if (!name) {
let isMovement = slotEl.dataset.subtype === 'movement';
slotEl.className = "visual-slot empty";
slotEl.innerHTML = "➕ 点击选择" + (slotEl.dataset.type === 'method' ? (isMovement ? "遁术" : "功法") : "神通");
return;
}
slotEl.className = "visual-slot";
let imgSrc = itemData ? getImgUrl(itemData.imgId) : "";
let imgHtml = imgSrc ? `<img src="${imgSrc}" class="slot-icon" onerror="this.style.display='none'">` : ;
slotEl.innerHTML = `${imgHtml}${name}✖`;
slotEl.querySelector('.slot-clear').onclick = function(e) {
e.stopPropagation();
let hiddenInput = slotEl.parentElement.querySelector('.hidden-val');
hiddenInput.value = "";
updateVisualSlot(slotEl, "", null);
hiddenInput.dispatchEvent(new Event('change', {bubbles: true}));
};
}
function sortStages() {
let container = document.getElementById('stages-container');
let blocks = Array.from(container.querySelectorAll('.stage-block'));
blocks.sort((a, b) => {
return parseInt(a.querySelector('.stage-weight-select').value) - parseInt(b.querySelector('.stage-weight-select').value);
});
blocks.forEach(b => container.appendChild(b));
}
function populateForgeDropdowns() {['weapon', 'armor', 'trinket'].forEach(function(part) {
var optionsHTML = '<option value="">-- 请选择词条 --</option>';
FORGE_DB[part].forEach(function(eff) { optionsHTML += '<option value="' + eff + '">' + eff + '</option>'; });
document.querySelectorAll('.part-' + part).forEach(function(select) {
if (select.options.length <= 1) { select.innerHTML = optionsHTML; }
});
});
}
function reverseEngineerRecipe(effect, part) {
var recipes =[];
var targetIndices = (part === 'weapon') ?[0,1,2,3,4] : (part === 'armor') ? [5,6] :[7,8,9];
function searchMatrix(matrix, yinYangLabel) {
for (var elem in matrix) {
var effects = matrix[elem].split('|');
var matchedTypes =[];
targetIndices.forEach(function(idx) { if (effects[idx] === effect) matchedTypes.push(EQUIP_TYPES[idx]); });
if (matchedTypes.length > 0) recipes.push("[" + yinYangLabel + "] + [" + elem + "系]材料 ➜ " + matchedTypes.join('/') + "");
}
}
searchMatrix(TIAN_YANG, "天阳"); searchMatrix(DI_YIN, "地阴");
return recipes;
}
function getAffixDescriptions(effect) {
var descs =[];
for (var key in AFFIX_DICT) {
if (effect.includes(key)) descs.push("【" + key + "】(灵力消耗:" + AFFIX_DICT[key].cost + "):" + AFFIX_DICT[key].desc);
}
return descs;
}
function updateMilestoneVisibility(stageBlock) {
var val = parseInt(stageBlock.querySelector('.stage-weight-select').value);
var gcBox = stageBlock.querySelector('.milestone-gc');
var dtBox = stageBlock.querySelector('.milestone-dt');
if (gcBox) gcBox.style.display = (val === 30 || val === 99) ? 'flex' : 'none';
if (dtBox) dtBox.style.display = (val === 50 || val === 99) ? 'flex' : 'none';
}
function updateRequirements(block) {
var reqList = block.querySelector('.req-list');
var daoReqs = {};
var otherReqs = new Set();
var daoRegex = /(.+?)(?:要求|达到|\s)*(初窥门径|略有小成|融会贯通|道之真境|大道已成)/;
function processCond(cond) {
if (cond && cond !== '无') {
cond.split('、').forEach(function(c) {
var match = c.match(daoRegex);
if (match) {
var daoName = match[1], levelStr = match[2], weight = window.WIKI_DAO_WEIGHT[levelStr];
if (!daoReqs[daoName] || weight > daoReqs[daoName].weight) daoReqs[daoName] = { level: levelStr, weight: weight };
} else {
otherReqs.add(c);
}
});
}
}
block.querySelectorAll('.method-select').forEach(function(select) { if (select.value && window.WikiData.methods[select.value]) processCond(window.WikiData.methods[select.value].condition); });
block.querySelectorAll('.spell-select').forEach(function(select) { if (select.value && window.WikiData.spells[select.value]) processCond(window.WikiData.spells[select.value].condition); });
var html = , hasReq = false;
for (var dao in daoReqs) { html += '
'; hasReq = true; } otherReqs.forEach(function(c) { html += '
'; hasReq = true; }); reqList.innerHTML = hasReq ? html : '
'; } function initWudaoUI() { var grid = document.getElementById('wudao-grid'); if (!grid) return; var html = ; for (var dao in DAO_CONFIG) { var color = DAO_CONFIG[dao].color; html += '
for (var c = 0; c < 5; c++) {
html += ' DAO_CONFIG[dao].cols[c].forEach(function(node) {
var isSym = NODE_DICT[node] && NODE_DICT[node].type === "symbiotic";
var classes = isSym ? 'dao-node symbiotic' : 'dao-node';
html += '});html += '
}html += '
';
}
grid.innerHTML = html;
document.querySelectorAll('.dao-node').forEach(function(el) {
el.addEventListener('click', function() {
if (this.classList.contains('locked')) return;
var dao = this.dataset.dao, node = this.dataset.node, col = parseInt(this.dataset.col);
var cost = NODE_DICT[node] ? NODE_DICT[node].cost :[1,2,4,6,8][col];
if (window.activeDaoNodes[node]) {
var nObj = window.activeDaoNodes[node];
if (nObj.type === "native" || nObj.source === dao) { delete window.activeDaoNodes[node]; currentWudaoPoints -= cost; }
} else {
if (currentWudaoPoints + cost > MAX_WUDAO_POINTS) { alert("悟道点已达上限 (" + MAX_WUDAO_POINTS + "点)!"); return; }
window.activeDaoNodes[node] = (NODE_DICT[node] && NODE_DICT[node].type === "symbiotic") ? { type: "symbiotic", source: dao } : { type: "native", dao: dao };
currentWudaoPoints += cost;
}
updateDaoLocks();
});
});
updateDaoLocks();
}
function updateDaoLocks() {
var changed = true;
while(changed) {
changed = false;
for (var dao in DAO_CONFIG) {
for (var c = 1; c < 5; c++) {
var isUnlocked = false;
DAO_CONFIG[dao].cols[c-1].forEach(function(prevNode) {
var obj = window.activeDaoNodes[prevNode];
if (obj && ((obj.type === "native" && obj.dao === dao) || (obj.type === "symbiotic" && obj.source === dao))) isUnlocked = true;
});
if (!isUnlocked) {
DAO_CONFIG[dao].cols[c].forEach(function(currNode) {
var obj = window.activeDaoNodes[currNode];
if (obj && (obj.type === "native" || (obj.type === "symbiotic" && obj.source === dao))) {
var cost = NODE_DICT[currNode] ? NODE_DICT[currNode].cost :[1,2,4,6,8][c];
delete window.activeDaoNodes[currNode];
currentWudaoPoints -= cost;
changed = true;
}
});
}
}
}
}
document.querySelectorAll('.dao-node').forEach(function(el) {
var dao = el.dataset.dao, node = el.dataset.node, col = parseInt(el.dataset.col);
if (window.activeDaoNodes[node]) { el.classList.add('active'); el.classList.remove('locked'); }
else {
el.classList.remove('active');
var isUnlocked = (col === 0);
if (col > 0) DAO_CONFIG[dao].cols[col-1].forEach(function(prevNode) {
var obj = window.activeDaoNodes[prevNode];
if (obj && ((obj.type === "native" && obj.dao === dao) || (obj.type === "symbiotic" && obj.source === dao))) isUnlocked = true;
});
if (isUnlocked) el.classList.remove('locked'); else el.classList.add('locked');
}
});
var wbtn = document.getElementById('btn-toggle-wudao');
if(wbtn) wbtn.innerText = wbtn.classList.contains('active') ? "❌ 收起全局悟道加点图 (" + currentWudaoPoints + " / 108 点)" : "➕ 展开全局悟道加点图 (" + currentWudaoPoints + " / 108 点)";
var hasKongQi = !!window.activeDaoNodes["控器"];
document.querySelectorAll('.slot-weapon2').forEach(function(sel) {
if (hasKongQi) { sel.disabled = false; if(sel.options[0].text.includes("未解锁")) sel.options[0].text = "-- 自定义(已解锁) --"; }
else { sel.disabled = true; sel.value = ""; sel.options[0].text = "未解锁(需控器)"; }
});
}
function exportBuildCode() {
var data = { talents: {}, dao: window.activeDaoNodes, stages:[] };
data.talents.diff = document.getElementById('game-difficulty').value;
data.talents.gender = document.getElementById('char-gender').value;
data.talents.role = document.getElementById('role-setting').value;
data.talents.root = document.getElementById('root-level').value;
data.talents.cbs =[];
document.querySelectorAll('.talent-cb:checked, .elem-cb:checked').forEach(function(cb) { data.talents.cbs.push(cb.nextElementSibling.innerText); });
document.querySelectorAll('.stage-block').forEach(function(block) {
var sData = { weight: block.querySelector('.stage-weight-select').value, methods: [], levels:[], equips: [], spells:[] };
var gcSels = block.querySelectorAll('.milestone-gc select');
if(gcSels.length > 1) { sData.gcTier = gcSels[0].value; sData.gcType = gcSels[1].value; }
var dtSel = block.querySelector('.milestone-dt select');
if(dtSel) sData.dtType = dtSel.value;
block.querySelectorAll('.method-select').forEach(function(s) { sData.methods.push(s.value); });
block.querySelectorAll('.level-select').forEach(function(s) { sData.levels.push(s.value); });
block.querySelectorAll('.equip-select').forEach(function(s) { sData.equips.push(s.value); });
block.querySelectorAll('.spell-select').forEach(function(s) { sData.spells.push(s.value); });
data.stages.push(sData);
});
var code = btoa(encodeURIComponent(JSON.stringify(data)));
var textarea = document.getElementById('build-code-input');
textarea.value = code; textarea.select(); document.execCommand('copy');
alert("✅ 成功!流派分享码已生成,并自动复制到了你的剪贴板!");
}
function importBuildCode() {
var code = document.getElementById('build-code-input').value.trim();
if(!code) return alert("❌ 请先在输入框内粘贴分享码!");
try {
var data = JSON.parse(decodeURIComponent(atob(code)));
document.getElementById('game-difficulty').value = data.talents.diff || "极难";
document.getElementById('char-gender').value = data.talents.gender || "女";
document.getElementById('role-setting').value = data.talents.role || "20";
document.getElementById('root-level').value = data.talents.root || "14";
document.querySelectorAll('.talent-cb, .elem-cb').forEach(function(cb) { cb.checked = false; });
document.querySelectorAll('.talent-cb, .elem-cb').forEach(function(cb) { if (data.talents.cbs.indexOf(cb.nextElementSibling.innerText) !== -1) cb.checked = true; });
document.getElementById('role-setting').dispatchEvent(new Event('change'));
window.activeDaoNodes = data.dao || {};
currentWudaoPoints = 0;
for (var node in window.activeDaoNodes) {
var c = NODE_DICT[node] ? NODE_DICT[node].cost : 0;
if (!c) { for(var d in DAO_CONFIG) { for(var col=0; col<5; col++) { if(DAO_CONFIG[d].cols[col].indexOf(node) !== -1) c =[1,2,4,6,8][col]; } } }
currentWudaoPoints += c;
}
updateDaoLocks();
var container = document.getElementById('stages-container');
container.innerHTML = ;
data.stages.forEach(function(sData) {
var newBlock = document.getElementById('stage-template').content.cloneNode(true).querySelector('.stage-block');
container.appendChild(newBlock);
let selEl = newBlock.querySelector('.stage-weight-select');
selEl.value = sData.weight;
selEl.dataset.oldValue = sData.weight;
updateMilestoneVisibility(newBlock);
var gcSels = newBlock.querySelectorAll('.milestone-gc select');
if(gcSels.length > 1 && sData.gcTier) { gcSels[0].value = sData.gcTier; gcSels[1].value = sData.gcType; }
var dtSel = newBlock.querySelector('.milestone-dt select');
if(dtSel && sData.dtType) dtSel.value = sData.dtType;
if(typeof populateForgeDropdowns === 'function') populateForgeDropdowns();
var mSels = newBlock.querySelectorAll('.method-select');
var vMSels = newBlock.querySelectorAll('.visual-slot[data-type="method"]');
var lSels = newBlock.querySelectorAll('.level-select');
var eSels = newBlock.querySelectorAll('.equip-select');
var spSels = newBlock.querySelectorAll('.spell-select');
var vSpSels = newBlock.querySelectorAll('.visual-slot[data-type="spell"]');
sData.levels.forEach(function(val, i) { if(lSels[i]) lSels[i].value = val; });
sData.equips.forEach(function(val, i) { if(eSels[i]) eSels[i].value = val; });
sData.methods.forEach(function(val, i) {
if(mSels[i]) { mSels[i].value = val; updateVisualSlot(vMSels[i], val, window.WikiData.methods[val]); }
});
sData.spells.forEach(function(val, i) {
if(spSels[i]) { spSels[i].value = val; updateVisualSlot(vSpSels[i], val, window.WikiData.spells[val]); }
});
updateRequirements(newBlock);
if (eSels[0]) eSels[0].dispatchEvent(new Event('change', {bubbles:true}));
});
sortStages();
alert("🎉 流派导入成功!页面已刷新为大能的构筑!");
} catch(e) { alert("❌ 解析失败!请检查分享码是否完整。"); console.error(e); }
}
function bindEvents() {
initFilters();
document.getElementById('btn-export-code').addEventListener('click', exportBuildCode);
document.getElementById('btn-import-code').addEventListener('click', importBuildCode);
document.getElementById('btn-generate-image').addEventListener('click', function() {
document.getElementById('btn-generate-image').click();
});
document.getElementById('add-stage-btn').addEventListener('click', function() {
let existingVals = Array.from(document.querySelectorAll('.stage-weight-select')).map(s => parseInt(s.value));
let availableWeights =[10, 20, 30, 40, 50, 99];
let nextVal = availableWeights.find(w => !existingVals.includes(w));
if (nextVal === undefined) return alert("❌ 所有境界阶段(包括毕业构筑)均已创建,无法继续添加!");
var newBlock = document.getElementById('stage-template').content.cloneNode(true).querySelector('.stage-block');
let selectEl = newBlock.querySelector('.stage-weight-select');
selectEl.value = nextVal;
selectEl.dataset.oldValue = nextVal;
updateMilestoneVisibility(newBlock);
document.getElementById('stages-container').appendChild(newBlock);
populateForgeDropdowns();
sortStages();
});
document.getElementById('stages-container').addEventListener('click', function(e) {
if (e.target.classList.contains('btn-remove')) {
e.target.closest('.stage-block').remove();
}
});
document.getElementById('btn-toggle-talent').addEventListener('click', function() {
var tc = document.getElementById('talent-container');
if (tc.style.display === 'block') { tc.style.display = 'none'; this.innerHTML = '➕ 添加开局天赋与造化要求 (可选)'; this.classList.remove('active'); }
else { tc.style.display = 'block'; this.innerHTML = '❌ 收起并取消开局天赋要求'; this.classList.add('active'); }
});
document.getElementById('btn-toggle-wudao').addEventListener('click', function() {
var wc = document.getElementById('wudao-container');
if (wc.style.display === 'block') { wc.style.display = 'none'; this.classList.remove('active'); }
else { wc.style.display = 'block'; this.classList.add('active'); }
updateDaoLocks();
});
document.getElementById('stages-container').addEventListener('change', function(e) {
var target = e.target;
var block = target.closest('.stage-block');
if (!block) return;
if (target.classList.contains('stage-weight-select')) {
let newVal = parseInt(target.value);
let duplicate = Array.from(document.querySelectorAll('.stage-weight-select')).find(s => s !== target && parseInt(s.value) === newVal);
if (duplicate) {
alert("❌ 该境界阶段已存在,一个阶段只能创建一次!");
target.value = target.dataset.oldValue;
return;
}
target.dataset.oldValue = newVal;
updateMilestoneVisibility(block);
sortStages();
return;
}
if (target.classList.contains('method-select') || target.classList.contains('level-select')) {
var row = target.closest('.slot-item');
var mSel = row.querySelector('.method-select');
var lSel = row.querySelector('.level-select');
var vSel = row.querySelector('.visual-slot');
var cWeight = parseInt(block.querySelector('.stage-weight-select').value);
var mName = mSel.value;
if (mName && window.WikiData.methods[mName]) {
var lIdx = parseInt(lSel.value.charAt(0)) - 1;
var reqStr = window.WikiData.methods[mName].reqs[lIdx];
var rWeight = window.WIKI_STAGE_WEIGHT[reqStr] || 0;
if (rWeight > cWeight && cWeight !== 99) {
alert("⚠️ 境界不足拦截!\n\n《" + mName + "》突破至" + lSel.value + "需要达到【" + reqStr + "】。\n你当前板块境界过低,已强制退回1层!");
lSel.value = "1层"; vSel.style.borderColor = "red"; setTimeout(function(){ vSel.style.borderColor = "#bdc3c7"; }, 2000);
}
}
}
if (target.classList.contains('equip-select')) {
var forgeList = block.querySelector('.forge-list');
var equips = block.querySelectorAll('.equip-select');
var combinedHtml = "";
equips.forEach(function(eq) {
var eff = eq.value;
if (eff) {
var partName = eq.parentElement.querySelector('.label-title').innerText;
var partType = eq.classList.contains('part-armor') ? 'armor' : (eq.classList.contains('part-trinket') ? 'trinket' : 'weapon');
var recipes = reverseEngineerRecipe(eff, partType);
var descs = getAffixDescriptions(eff);
combinedHtml += "
配方:
" + recipes.join('
') + "
"; if (descs.length > 0) combinedHtml += "
') + "
";
}
});
forgeList.innerHTML = combinedHtml || "请在上方选择所需的装备词条...";
}
if (target.classList.contains('method-select') || target.classList.contains('spell-select') || target.classList.contains('level-select')) {
updateRequirements(block);
}
});
var pText = document.getElementById('pointsText'), pSpan = document.getElementById('currentPoints');
var roleSel = document.getElementById('role-setting'), rootSel = document.getElementById('root-level');
function calcP() {
var u = parseInt(rootSel.value);
document.querySelectorAll('.talent-cb:checked').forEach(function(cb){ u += parseInt(cb.getAttribute('data-cost')); });
var cur = parseInt(roleSel.value) - u;
pSpan.innerText = cur;
if(cur < 0) pText.classList.add('error'); else pText.classList.remove('error');
}
roleSel.addEventListener('change', calcP); rootSel.addEventListener('change', function(){ document.querySelectorAll('.elem-cb').forEach(function(c){c.checked=false;}); calcP();});
document.querySelectorAll('.talent-cb').forEach(function(cb){ cb.addEventListener('change', calcP); });
document.querySelectorAll('.bg-cb').forEach(function(cb){ cb.addEventListener('change', function(){ if(document.querySelectorAll('.bg-cb:checked').length>2){ this.checked=false; document.getElementById('warn-bg').style.display='inline'; setTimeout(function(){document.getElementById('warn-bg').style.display='none'},1500); calcP(); } })});
document.querySelectorAll('.mutex-cb').forEach(function(cb){ cb.addEventListener('change', function(){ if(this.checked){ var g=this.getAttribute('data-mutex'), cfl=false, _t=this; document.querySelectorAll('.mutex-cb[data-mutex="'+g+'"]').forEach(function(o){ if(o!==_t && o.checked){ o.checked=false; cfl=true;} }); if(cfl){ document.querySelectorAll('.warn-mutex').forEach(function(w){ w.style.display='inline'; setTimeout(function(){w.style.display='none'},2000); });} calcP(); } })});
document.querySelectorAll('.elem-cb').forEach(function(cb){ cb.addEventListener('change', function(){ var al=parseInt(rootSel.options[rootSel.selectedIndex].getAttribute('data-count')); if(document.querySelectorAll('.elem-cb:checked').length>al){ this.checked=false; document.getElementById('warn-elem').style.display='inline'; setTimeout(function(){document.getElementById('warn-elem').style.display='none'},1500);} })});
calcP();
}
function initApp() {
bindEvents();
initWudaoUI();
document.getElementById('add-stage-btn').click();
fetchWikiData();
}
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initApp); } else { setTimeout(initApp, 100); }
/**
* ========================================================== * 终极绝杀模块:流派精美长图生成引擎 (完美下载+高清图标版) * ========================================================== */
const imageModalHTML = `
`;
document.body.insertAdjacentHTML('beforeend', imageModalHTML);
document.getElementById('btn-generate-image').addEventListener('click', function() {
let btn = this; btn.innerText = "⏳ 正在拉取高清图库..."; btn.disabled = true;
if (typeof html2canvas === 'undefined') {
let script = document.createElement('script');
script.src = 'https://cdn.staticfile.net/html2canvas/1.4.1/html2canvas.min.js';
script.onload = () => buildAndCapture(btn);
document.head.appendChild(script);
} else {
buildAndCapture(btn);
}
});
function buildAndCapture(btn) {
btn.innerText = "📸 正在精美排版中...";
let drawBoard = document.createElement('div');
drawBoard.style.cssText = "position:absolute; top:-9999px; left:-9999px; width:850px; background:#f5f6fa; padding:30px; font-family:'Microsoft YaHei', sans-serif; color:#2c3e50; box-sizing:border-box;";
let html = `
觅长生 · 流派构筑分享
Powered by BWIKI 觅长生WIKI
`;
let talentContainer = document.getElementById('talent-container');
if (talentContainer.style.display === 'block') {
let diff = document.getElementById('game-difficulty').value;
let gender = document.getElementById('char-gender').value;
let root = document.getElementById('root-level').options[document.getElementById('root-level').selectedIndex].text.split(' ')[0];
html += `
document.querySelectorAll('.talent-section').forEach(sec => {
let title = sec.querySelector('.talent-title').childNodes[0].nodeValue.trim();
let cbs = sec.querySelectorAll('input[type="checkbox"]:checked');
if (cbs.length > 0) {
html += ` ${title}:
cbs.forEach(cb => {
let t = cb.nextElementSibling.innerText.split(' ')[0];
html += `${t}`;
});
html += ` }
});
html += ``;
}
let daoGroups = {};
for (let node in window.activeDaoNodes) {
let d = window.activeDaoNodes[node];
let daoName = d.type === 'native' ? d.dao : d.source;
if(!daoGroups[daoName]) daoGroups[daoName] = [];
daoGroups[daoName].push(node);
}
if (Object.keys(daoGroups).length > 0) {
html += `
☯️ 全局悟道加点
`; for (let daoName in daoGroups) {
html += ` daoGroups[daoName].forEach(n => html += `${n}`);
html += `}html += `
`;
}
document.querySelectorAll('.stage-block').forEach(block => {
let stageName = block.querySelector('.stage-weight-select').options[block.querySelector('.stage-weight-select').selectedIndex].text;
html += `
${stageName}
`; let methodsHTML = ;
let mInputs = block.querySelectorAll('.method-select');
let mLevels = block.querySelectorAll('.level-select');
let mTitles =["主修", "辅修", "辅修", "辅修", "辅修", "遁术"];
mInputs.forEach((input, i) => {
let name = input.value;
if (name && window.WikiData.methods[name]) {
let level = mLevels[i].value;
let bg = i === 0 ? '#fff3e0' : '#f8f9fa';
let border = i === 0 ? '#f39c12' : '#dcdde1';
let visibleImg = input.parentElement.querySelector('img.slot-icon');
let imgSrc = visibleImg ? (visibleImg.currentSrc || visibleImg.src) : "";
methodsHTML += ``;
}
});
if (methodsHTML) {
html += `🕮 功法配置
}
let spellsHTML = ;
block.querySelectorAll('.spell-select').forEach(input => {
let name = input.value;
if (name && window.WikiData.spells[name]) {
let visibleImg = input.parentElement.querySelector('img.slot-icon');
let imgSrc = visibleImg ? (visibleImg.currentSrc || visibleImg.src) : "";
spellsHTML += ``;
}
});
if (spellsHTML) {
html += `🔮 神通配置
}
let forgeHtml = block.querySelector('.forge-list').innerHTML;
if (forgeHtml && !forgeHtml.includes('请在上方选择')) {
html += `⚔️ 装备炼制配方
}
let reqHtml = block.querySelector('.req-list').innerHTML;
if (reqHtml && !reqHtml.includes('自动计算')) {
html += `📌 学习前置要求
- ${reqHtml}
}html += `
`;
});
html += ``;
drawBoard.innerHTML = html; document.body.appendChild(drawBoard);
let imgs = Array.from(drawBoard.querySelectorAll('img'));
let promises = imgs.map(img => new Promise(resolve => {
if (img.complete) return resolve();
img.onload = resolve;
img.onerror = resolve;
}));
Promise.all(promises).then(() => {
setTimeout(() => {
html2canvas(drawBoard, {
useCORS: true,
scale: 2,
backgroundColor: '#f5f6fa'
}).then(canvas => {
let imgBase64 = canvas.toDataURL("image/png");
let outputContainer = document.getElementById('image-render-output');
outputContainer.innerHTML = `<img src="${imgBase64}" style="width: 100%; border-radius: 8px; display: block; box-shadow: 0 4px 10px rgba(0,0,0,0.1);">`;
document.getElementById('image-result-modal').style.display = 'flex';
let downloadLink = document.createElement('a');
downloadLink.href = imgBase64;
downloadLink.download = '觅长生_流派构筑分享.png';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
document.body.removeChild(drawBoard);
btn.innerText = "📸 生成精美长图分享";
btn.disabled = false;
}).catch(err => {
alert("图片绘制被浏览器拦截!跨域失败。");
document.body.removeChild(drawBoard);
btn.innerText = "📸 生成精美长图分享";
btn.disabled = false;
});
}, 100);
});
} </script>


沪公网安备 31011002002714 号