卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁Card.js”︁的源代码
←
MediaWiki:Card.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
(function() { 'use strict'; // 加载CSS mw.loader.load('/index.php?title=Mediawiki:Card.css&action=raw&ctype=text/css', 'text/css'); // 调试日志 console.log('Card Manager: 脚本已加载'); // 卡牌管理器类 class CardManager { constructor() { console.log('Card Manager: 初始化中...'); this.currentFighter = ''; this.cards = {}; this.currentCard = null; this.fighters = ['示例战斗员1', '示例战斗员2']; // 默认战斗员列表 this.defaultData = { order: [], ego: '' }; this.cardData = { name: '', displayname: '', art: '', group: '', rarity: '', god: '', ap: '', type: '攻击', dict: '', desc_global: '', sub: '', isinspiration: false, isgod_inspiration: false, inspirations: [], god_inspirations: { circen: [], diallos: [], nihilum: [], secred: [], vitor: [] } }; } async init() { console.log('Card Manager: 开始初始化'); await this.loadFighters(); this.render(); console.log('Card Manager: 初始化完成'); } async loadFighters() { try { const api = new mw.Api(); const response = await api.get({ action: 'query', list: 'categorymembers', cmtitle: 'Category:战斗员', cmlimit: 500 }); if (response.query && response.query.categorymembers) { this.fighters = response.query.categorymembers.map(page => page.title); console.log('Card Manager: 加载了', this.fighters.length, '个战斗员'); } } catch (error) { console.error('Card Manager: 加载战斗员列表失败:', error); } } render() { console.log('Card Manager: 开始渲染'); // 获取内容容器 const contentDiv = document.getElementById('mw-content-text'); if (!contentDiv) { console.error('Card Manager: 找不到内容容器'); return; } // 清空现有内容 contentDiv.innerHTML = ''; // 创建主容器 const container = document.createElement('div'); container.className = 'card-manager'; // 左侧面板 const leftPanel = document.createElement('div'); leftPanel.className = 'card-input-panel'; leftPanel.appendChild(this.renderFighterSelect()); leftPanel.appendChild(this.renderDefaultInfo()); leftPanel.appendChild(this.renderCardInput()); // 中间面板 const middlePanel = document.createElement('div'); middlePanel.className = 'card-list-panel'; middlePanel.appendChild(this.renderCardLists()); // 右侧面板 const rightPanel = document.createElement('div'); rightPanel.className = 'card-preview-panel'; rightPanel.appendChild(this.renderPreview()); container.appendChild(leftPanel); container.appendChild(middlePanel); container.appendChild(rightPanel); contentDiv.appendChild(container); console.log('Card Manager: 渲染完成'); } renderFighterSelect() { const container = document.createElement('div'); container.className = 'form-group'; const label = document.createElement('div'); label.className = 'form-label'; label.textContent = '当前战斗员'; const selectContainer = document.createElement('div'); selectContainer.className = 'custom-select'; const display = document.createElement('div'); display.className = 'select-display'; display.textContent = this.currentFighter || '请选择战斗员...'; const arrow = document.createElement('span'); arrow.className = 'select-arrow'; arrow.textContent = '▼'; display.appendChild(arrow); const dropdown = document.createElement('div'); dropdown.className = 'select-dropdown'; this.fighters.forEach(fighter => { const option = document.createElement('div'); option.className = 'select-option'; option.textContent = fighter; if (fighter === this.currentFighter) { option.classList.add('selected'); } option.onclick = () => { this.currentFighter = fighter; display.firstChild.textContent = fighter; dropdown.querySelectorAll('.select-option').forEach(o => o.classList.remove('selected')); option.classList.add('selected'); dropdown.classList.remove('active'); this.loadFighterData(); }; dropdown.appendChild(option); }); display.onclick = (e) => { e.stopPropagation(); dropdown.classList.toggle('active'); }; document.addEventListener('click', () => { dropdown.classList.remove('active'); }); selectContainer.appendChild(display); selectContainer.appendChild(dropdown); container.appendChild(label); container.appendChild(selectContainer); return container; } renderDefaultInfo() { const container = document.createElement('div'); container.className = 'default-info-section'; const title = document.createElement('div'); title.className = 'section-title'; title.textContent = '默认信息'; container.appendChild(title); // 卡牌顺序 const orderGroup = document.createElement('div'); orderGroup.className = 'form-group'; const orderLabel = document.createElement('div'); orderLabel.className = 'form-label'; orderLabel.textContent = '卡牌顺序(card.order)'; const orderInput = document.createElement('div'); orderInput.className = 'custom-input'; orderInput.contentEditable = true; orderInput.textContent = this.defaultData.order.join(','); orderInput.addEventListener('input', () => { this.defaultData.order = orderInput.textContent.split(',').map(s => s.trim()).filter(s => s); this.updatePreview(); }); orderGroup.appendChild(orderLabel); orderGroup.appendChild(orderInput); container.appendChild(orderGroup); // 属性 const egoGroup = document.createElement('div'); egoGroup.className = 'form-group'; const egoLabel = document.createElement('div'); egoLabel.className = 'form-label'; egoLabel.textContent = '属性(ego)'; const egoInput = document.createElement('div'); egoInput.className = 'custom-input'; egoInput.contentEditable = true; egoInput.textContent = this.defaultData.ego; egoInput.addEventListener('input', () => { this.defaultData.ego = egoInput.textContent; this.updatePreview(); }); egoGroup.appendChild(egoLabel); egoGroup.appendChild(egoInput); container.appendChild(egoGroup); return container; } renderCardInput() { const container = document.createElement('div'); const title = document.createElement('div'); title.className = 'section-title'; title.textContent = '卡牌数据'; container.appendChild(title); // 卡牌名称 container.appendChild(this.createInputField('卡牌名称', 'name')); // 显示名称 container.appendChild(this.createInputField('显示名称(displayname)', 'displayname')); // 图片 container.appendChild(this.createInputField('图片(art)', 'art')); // 卡组选择 container.appendChild(this.createGroupSelect()); // 稀有度 container.appendChild(this.createRaritySelect()); // 神明 container.appendChild(this.createGodSelect()); // AP container.appendChild(this.createInputField('AP', 'ap')); // 卡牌类型 container.appendChild(this.createTypeSelect()); // 机制 container.appendChild(this.createInputField('机制(dict)', 'dict')); // 描述 const descGroup = document.createElement('div'); descGroup.className = 'form-group'; const descLabel = document.createElement('div'); descLabel.className = 'form-label'; descLabel.textContent = '描述(desc_global)'; const formatButtons = this.createFormatButtons(); const descInput = document.createElement('div'); descInput.className = 'custom-textarea'; descInput.contentEditable = true; descInput.textContent = this.cardData.desc_global; descInput.id = 'desc-input'; descInput.addEventListener('input', () => { this.cardData.desc_global = descInput.textContent; this.updatePreview(); }); descGroup.appendChild(descLabel); descGroup.appendChild(formatButtons); descGroup.appendChild(descInput); container.appendChild(descGroup); // 衍生卡牌 container.appendChild(this.createInputField('衍生卡牌(sub)', 'sub')); // 是否存在灵光一闪 container.appendChild(this.createCheckboxField('是否存在灵光一闪', 'isinspiration')); // 是否存在神光一闪 container.appendChild(this.createCheckboxField('是否存在神光一闪', 'isgod_inspiration')); // 按钮组 const btnGroup = document.createElement('div'); btnGroup.className = 'btn-group'; const saveBtn = document.createElement('div'); saveBtn.className = 'btn btn-primary'; saveBtn.textContent = '保存卡牌'; saveBtn.onclick = () => this.saveCard(); const newBtn = document.createElement('div'); newBtn.className = 'btn btn-success'; newBtn.textContent = '新建卡牌'; newBtn.onclick = () => this.newCard(); btnGroup.appendChild(saveBtn); btnGroup.appendChild(newBtn); container.appendChild(btnGroup); return container; } createInputField(label, field) { const group = document.createElement('div'); group.className = 'form-group'; const labelDiv = document.createElement('div'); labelDiv.className = 'form-label'; labelDiv.textContent = label; const input = document.createElement('div'); input.className = 'custom-input'; input.contentEditable = true; input.textContent = this.cardData[field] || ''; input.addEventListener('input', () => { this.cardData[field] = input.textContent; this.updatePreview(); }); group.appendChild(labelDiv); group.appendChild(input); return group; } createCheckboxField(label, field) { const group = document.createElement('div'); group.className = 'form-group'; const labelDiv = document.createElement('div'); labelDiv.className = 'form-label'; labelDiv.textContent = label; const checkboxContainer = document.createElement('div'); checkboxContainer.className = 'checkbox-group'; const checkbox = document.createElement('div'); checkbox.className = 'custom-checkbox'; if (this.cardData[field]) { checkbox.classList.add('checked'); } const statusLabel = document.createElement('div'); statusLabel.textContent = this.cardData[field] ? '是' : '否'; checkbox.onclick = () => { checkbox.classList.toggle('checked'); this.cardData[field] = checkbox.classList.contains('checked'); statusLabel.textContent = this.cardData[field] ? '是' : '否'; this.updatePreview(); }; checkboxContainer.appendChild(checkbox); checkboxContainer.appendChild(statusLabel); group.appendChild(labelDiv); group.appendChild(checkboxContainer); return group; } createFormatButtons() { const container = document.createElement('div'); container.className = 'format-buttons'; const buttons = [ { label: '蓝色文本', class: 'blue', template: '{{文本|蓝|%s}}' }, { label: '绿色文本', class: 'green', template: '{{文本|绿|%s}}' }, { label: '绿色描边', class: 'green', template: '{{描边|绿|%s}}' }, { label: '词典', class: '', template: '{{词典|%s}}' }, { label: '换行', class: '', template: '<br>' } ]; buttons.forEach(btn => { const button = document.createElement('div'); button.className = 'format-btn ' + btn.class; button.textContent = btn.label; button.onclick = () => { const textarea = document.getElementById('desc-input'); if (textarea) { this.insertTemplate(textarea, btn.template); } }; container.appendChild(button); }); return container; } insertTemplate(textarea, template) { const selection = window.getSelection(); const selectedText = selection.toString(); if (template === '<br>') { document.execCommand('insertHTML', false, '<br>'); } else { const result = template.replace('%s', selectedText || '选择文字'); document.execCommand('insertText', false, result); } this.cardData.desc_global = textarea.textContent; this.updatePreview(); } createGroupSelect() { const group = document.createElement('div'); group.className = 'form-group'; const label = document.createElement('div'); label.className = 'form-label'; label.textContent = '卡组(group)'; const container = document.createElement('div'); container.className = 'group-options'; const groups = ['自我意识技能', '起始卡牌', '独特卡牌', '灵光一闪', '神光一闪']; groups.forEach(groupName => { const option = document.createElement('div'); option.className = 'group-option'; option.textContent = groupName; if (this.cardData.group === groupName) { option.classList.add('selected'); } option.onclick = () => { container.querySelectorAll('.group-option').forEach(o => o.classList.remove('selected')); option.classList.add('selected'); this.cardData.group = groupName; this.updatePreview(); }; container.appendChild(option); }); group.appendChild(label); group.appendChild(container); return group; } createRaritySelect() { const group = document.createElement('div'); group.className = 'form-group'; const label = document.createElement('div'); label.className = 'form-label'; label.textContent = '稀有度(rarity)'; const container = document.createElement('div'); container.className = 'rarity-options'; const rarities = ['白', '蓝', '橙', '彩']; rarities.forEach(rarity => { const option = document.createElement('div'); option.className = 'rarity-option'; option.textContent = rarity; if (this.cardData.rarity === rarity) { option.classList.add('selected'); } option.onclick = () => { container.querySelectorAll('.rarity-option').forEach(o => o.classList.remove('selected')); option.classList.add('selected'); this.cardData.rarity = rarity; this.updatePreview(); }; container.appendChild(option); }); group.appendChild(label); group.appendChild(container); return group; } createGodSelect() { const group = document.createElement('div'); group.className = 'form-group'; const label = document.createElement('div'); label.className = 'form-label'; label.textContent = '神明'; const container = document.createElement('div'); container.className = 'god-options'; const gods = ['circen', 'diallos', 'nihilum', 'secred', 'vitor']; gods.forEach(god => { const option = document.createElement('div'); option.className = 'god-option'; option.textContent = god; if (this.cardData.god === god) { option.classList.add('selected'); } option.onclick = () => { container.querySelectorAll('.god-option').forEach(o => o.classList.remove('selected')); option.classList.add('selected'); this.cardData.god = god; this.updatePreview(); }; container.appendChild(option); }); group.appendChild(label); group.appendChild(container); return group; } createTypeSelect() { const group = document.createElement('div'); group.className = 'form-group'; const label = document.createElement('div'); label.className = 'form-label'; label.textContent = '卡牌类型(type)'; const container = document.createElement('div'); container.className = 'type-options'; const types = ['攻击', '技能', '强化']; types.forEach(type => { const option = document.createElement('div'); option.className = 'type-option'; option.textContent = type; if (this.cardData.type === type) { option.classList.add('selected'); } option.onclick = () => { container.querySelectorAll('.type-option').forEach(o => o.classList.remove('selected')); option.classList.add('selected'); this.cardData.type = type; this.updatePreview(); }; container.appendChild(option); }); group.appendChild(label); group.appendChild(container); return group; } renderCardLists() { const container = document.createElement('div'); const title = document.createElement('div'); title.className = 'panel-title'; title.textContent = '卡牌列表'; container.appendChild(title); const listContainer = document.createElement('div'); listContainer.className = 'list-container'; listContainer.id = 'card-list'; this.updateCardList(listContainer); container.appendChild(listContainer); return container; } updateCardList(container) { container.innerHTML = ''; const cardNames = Object.keys(this.cards); if (cardNames.length === 0) { const empty = document.createElement('div'); empty.className = 'list-empty'; empty.textContent = '暂无卡牌'; container.appendChild(empty); return; } cardNames.forEach(name => { const card = this.cards[name]; const item = document.createElement('div'); item.className = 'card-list-item'; const info = document.createElement('div'); const nameDiv = document.createElement('div'); nameDiv.className = 'card-list-item-name'; nameDiv.textContent = name; const detailDiv = document.createElement('div'); detailDiv.className = 'card-list-item-info'; detailDiv.textContent = `${card.type || '攻击'} | AP:${card.ap || 0} | ${card.rarity || ''}`; info.appendChild(nameDiv); info.appendChild(detailDiv); const deleteBtn = document.createElement('div'); deleteBtn.className = 'delete-btn'; deleteBtn.textContent = '删除'; deleteBtn.onclick = (e) => { e.stopPropagation(); if (confirm(`确定要删除卡牌"${name}"吗?`)) { delete this.cards[name]; this.updateCardList(container); this.updatePreview(); if (this.currentCard === name) { this.newCard(); } } }; item.appendChild(info); item.appendChild(deleteBtn); item.onclick = () => { this.loadCard(name); container.querySelectorAll('.card-list-item').forEach(i => i.classList.remove('active')); item.classList.add('active'); }; container.appendChild(item); }); } renderPreview() { const container = document.createElement('div'); const title = document.createElement('div'); title.className = 'panel-title'; title.textContent = 'Lua代码预览'; container.appendChild(title); const preview = document.createElement('div'); preview.className = 'preview-code'; preview.id = 'code-preview'; container.appendChild(preview); const copyBtn = document.createElement('div'); copyBtn.className = 'btn btn-primary'; copyBtn.textContent = '复制代码'; copyBtn.style.marginTop = '10px'; copyBtn.onclick = () => this.copyCode(); container.appendChild(copyBtn); this.updatePreview(); return container; } updatePreview() { const preview = document.getElementById('code-preview'); if (!preview) return; preview.textContent = this.generateLuaCode(); } generateLuaCode() { let code = 'local card = {}\n\n'; if (this.defaultData.order.length > 0) { code += `card.order = { "${this.defaultData.order.join(',')}" }\n\n`; } code += 'card.info = {\n'; if (this.defaultData.ego) { code += ` ego = "${this.defaultData.ego}",\n`; } code += '}\n\n'; Object.keys(this.cards).forEach(name => { const card = this.cards[name]; code += this.generateCardCode(name, card); }); code += 'return card'; return code; } generateCardCode(name, card) { let code = `card["${name}"] = {\n`; code += ' base = {\n'; if (card.displayname) code += ` displayname = "${card.displayname}",\n`; if (card.art) code += ` art = "${card.art}",\n`; if (card.group) code += ` group = "${card.group}",\n`; if (card.rarity) code += ` rarity = "${card.rarity}",\n`; if (card.ap) code += ` ap = ${isNaN(card.ap) ? `"${card.ap}"` : card.ap},\n`; if (card.type) code += ` type = "${card.type}",\n`; if (card.dict) code += ` dict = "${card.dict}",\n`; if (card.desc_global) { const desc = card.desc_global.replace(/\n/g, '<br>').replace(/"/g, '\\"'); code += ` desc_global = "${desc}",\n`; } if (card.sub) code += ` sub = "${card.sub}",\n`; if (card.isinspiration) code += ` isinspiration = 1,\n`; if (card.isgod_inspiration) code += ` isgod_inspiration = 1,\n`; code += ' },\n'; code += '}\n\n'; return code; } saveCard() { if (!this.cardData.name) { alert('请输入卡牌名称!'); return; } this.cards[this.cardData.name] = JSON.parse(JSON.stringify(this.cardData)); this.currentCard = this.cardData.name; if (!this.defaultData.order.includes(this.cardData.name)) { this.defaultData.order.push(this.cardData.name); } const listContainer = document.getElementById('card-list'); if (listContainer) { this.updateCardList(listContainer); } this.updatePreview(); alert('卡牌保存成功!'); } newCard() { this.currentCard = null; this.cardData = { name: '', displayname: '', art: '', group: '', rarity: '', god: '', ap: '', type: '攻击', dict: '', desc_global: '', sub: '', isinspiration: false, isgod_inspiration: false, inspirations: [], god_inspirations: { circen: [], diallos: [], nihilum: [], secred: [], vitor: [] } }; this.render(); } loadCard(name) { if (!this.cards[name]) return; this.currentCard = name; this.cardData = JSON.parse(JSON.stringify(this.cards[name])); this.render(); } async loadFighterData() { if (!this.currentFighter) return; try { const api = new mw.Api(); const moduleName = `模块:卡牌/${this.currentFighter}`; const response = await api.get({ action: 'query', prop: 'revisions', titles: moduleName, rvprop: 'content', rvslots: 'main' }); const pages = response.query.pages; const page = Object.values(pages)[0]; if (page.revisions) { const content = page.revisions[0].slots.main['*']; console.log('Card Manager: 加载了战斗员数据'); } } catch (error) { console.error('Card Manager: 加载战斗员数据失败:', error); } } copyCode() { const code = this.generateLuaCode(); const textarea = document.createElement('textarea'); textarea.value = code; textarea.style.position = 'fixed'; textarea.style.opacity = '0'; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); alert('代码已复制到剪贴板!'); } } // 初始化函数 function initCardManager() { console.log('Card Manager: 准备启动'); const manager = new CardManager(); manager.init(); } // 在页面加载完成后启动 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { mw.loader.using(['mediawiki.api']).then(initCardManager); }); } else { mw.loader.using(['mediawiki.api']).then(initCardManager); } })();
该页面使用的模板:
模板:图标
(
查看源代码
)
模板:描边
(
查看源代码
)
模板:描边/颜色
(
查看源代码
)
模板:文本
(
查看源代码
)
模板:词典
(
查看源代码
)
模块:文本
(
查看源代码
)
模块:词典
(
查看源代码
)
模块:词典/data
(
查看源代码
)
返回
MediaWiki:Card.js
。