配队模拟器:修订间差异
来自卡厄思梦境WIKI
创建页面,内容为“<script> (function() { 'use strict'; // ========== 工具函数 ========== function show(el) { if (el) el.style.display = 'block'; } function hide(el) { if (el) el.style.display = 'none'; } // ========== 战斗员选择 ========== const characterBox = document.getElementById('character-box'); const selectedCharacter = document.getElementById('selected-character'); characterBox.addEventListener('click', function(e) { e.…” |
无编辑摘要 |
||
| (未显示同一用户的33个中间版本) | |||
| 第1行: | 第1行: | ||
<!-- 加载html2canvas库 --> | |||
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> | |||
<script> | <script> | ||
(function() { | (function() { | ||
' | // 等待DOM加载完成 | ||
function initTeamSimulator() { | |||
// 为每个角色单元保存独立的状态 | |||
var characterUnits = {}; | |||
var currentActiveUnit = null; | |||
// 初始化所有角色单元 | |||
document.querySelectorAll('.character-unit').forEach(function(unit) { | |||
var unitIndex = unit.getAttribute('data-unit-index'); | |||
characterUnits[unitIndex] = { | |||
characterName: null, | |||
characterClass: null, | |||
cardIdCounter: 0, | |||
selectedCards: {} | |||
}; | |||
}); | |||
// ========== 保存为图片功能 ========== | |||
document.getElementById('save-team-btn').addEventListener('click', function() { | |||
var btn = this; | |||
var originalText = btn.textContent; | |||
btn.textContent = '生成中...'; | |||
btn.style.pointerEvents = 'none'; | |||
var contentElement = document.getElementById('team-content'); | |||
// 临时隐藏删除按钮 | |||
var deleteButtons = contentElement.querySelectorAll('.card-delete-btn'); | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'none'; | |||
}); | |||
html2canvas(contentElement, { | |||
backgroundColor: '#ffffff', | |||
scale: 2, | |||
logging: false, | |||
useCORS: true, | |||
allowTaint: true | |||
}).then(function(canvas) { | |||
// 恢复删除按钮 | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'flex'; | |||
}); | |||
// 下载图片 | |||
var link = document.createElement('a'); | |||
link.download = '配队方案_' + new Date().getTime() + '.png'; | |||
link.href = canvas.toDataURL('image/png'); | |||
link.click(); | |||
btn.textContent = originalText; | |||
btn.style.pointerEvents = 'auto'; | |||
}).catch(function(error) { | |||
console.error('保存失败:', error); | |||
alert('保存失败,请重试'); | |||
// 恢复删除按钮 | |||
deleteButtons.forEach(function(btn) { | |||
btn.style.display = 'flex'; | |||
}); | |||
btn.textContent = originalText; | |||
btn.style.pointerEvents = 'auto'; | |||
}); | |||
}); | |||
// 点击角色槽位显示选择窗口 | |||
document.querySelectorAll('.character-slot').forEach(function(slot) { | |||
slot.addEventListener('click', function() { | |||
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index'); | |||
document.getElementById('character-modal').style.display = 'block'; | |||
}); | |||
}); | |||
// 关闭角色选择窗口 | |||
document.getElementById('close-character-modal').addEventListener('click', function() { | |||
document.getElementById('character-modal').style.display = 'none'; | |||
}); | |||
// 点击遮罩层关闭窗口 | |||
document.getElementById('character-modal').addEventListener('click', function(e) { | |||
if (e.target === this) { | |||
this.style.display = 'none'; | |||
} | |||
}); | |||
// 加载战斗员卡牌 - 支持多角色 | |||
function loadCharacterCards(characterName, unitIndex) { | |||
if (!characterName) { | |||
console.error('战斗员名称为空'); | |||
return; | |||
} | |||
var unitData = characterUnits[unitIndex]; | |||
unitData.characterName = characterName; | |||
console.log('加载战斗员卡牌:', characterName, '单元:', unitIndex); | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | |||
var deckArea = unit.querySelector('.deck-area'); | |||
// 显示加载状态 | |||
var placeholder = deckArea.querySelector('.deck-placeholder'); | |||
if (placeholder) { | |||
placeholder.textContent = '加载中...'; | |||
placeholder.style.fontSize = '18px'; | |||
placeholder.style.color = '#999'; | |||
} | |||
var apiUrl = mw.util.wikiScript('api'); | |||
var params = { | |||
action: 'parse', | |||
format: 'json', | |||
text: '{{#invoke:配队/卡牌|deck|' + characterName + '}}', | |||
contentmodel: 'wikitext', | |||
disablelimitreport: true, | |||
wrapoutputclass: '' | |||
}; | |||
fetch(apiUrl + '?' + new URLSearchParams(params)) | |||
.then(response => response.json()) | |||
.then(data => { | |||
if (data.parse && data.parse.text) { | |||
// 清空并添加卡牌 | |||
deckArea.innerHTML = data.parse.text['*']; | |||
// 重置该单元的卡牌状态 | |||
unitData.selectedCards = {}; | |||
unitData.cardIdCounter = 0; | |||
setTimeout(function() { | |||
initializeCardFeatures(unitIndex); | |||
}, 100); | |||
} else { | |||
if (placeholder) { | |||
placeholder.textContent = '加载失败'; | |||
placeholder.style.color = 'red'; | |||
} | |||
} | |||
}) | |||
.catch(error => { | |||
console.error('加载卡牌失败:', error); | |||
if (placeholder) { | |||
placeholder.textContent = '加载出错'; | |||
placeholder.style.color = 'red'; | |||
} | |||
}); | |||
} | |||
// 初始化卡牌功能 | |||
function initializeCardFeatures(unitIndex) { | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | |||
var unitData = characterUnits[unitIndex]; | |||
var deckArea = unit.querySelector('.deck-area'); | |||
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper'); | |||
wrappers.forEach(function(wrapper) { | |||
var card = wrapper.querySelector('.card-small-wrapper'); | |||
if (!card) return; | |||
// 确保wrapper样式正确 | |||
wrapper.style.flexShrink = '0'; | |||
wrapper.style.display = 'inline-block'; | |||
var uniqueId = 'deck-card-' + unitIndex + '-' + (++unitData.cardIdCounter); | |||
wrapper.setAttribute('data-unique-id', uniqueId); | |||
wrapper.setAttribute('data-unit-index', unitIndex); | |||
unitData.selectedCards[uniqueId] = { | |||
module: wrapper.getAttribute('data-module') || unitData.characterName, | |||
cardName: wrapper.getAttribute('data-card'), | |||
variantType: null, | |||
variantParam: null, | |||
variantIndex: null | |||
}; | |||
if (!card.querySelector('.card-delete-btn')) { | |||
var deleteBtn = document.createElement('div'); | |||
deleteBtn.className = 'card-delete-btn'; | |||
deleteBtn.innerHTML = '×'; | |||
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;'; | |||
deleteBtn.addEventListener('click', function(e) { | |||
e.stopPropagation(); | |||
wrapper.remove(); | |||
delete unitData.selectedCards[uniqueId]; | |||
// 如果没有卡牌了,显示占位符 | |||
checkAndShowPlaceholder(unitIndex); | |||
}); | |||
card.style.position = 'relative'; | |||
card.appendChild(deleteBtn); | |||
} | |||
}); | |||
setupGlobalModalListener(); | |||
} | |||
// 检查并显示占位符 | |||
function checkAndShowPlaceholder(unitIndex) { | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]'); | |||
var deckArea = unit.querySelector('.deck-area'); | |||
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper'); | |||
if (wrappers.length === 0) { | |||
deckArea.innerHTML = '<div class="deck-placeholder" style="width: 100%; text-align: center; font-size: 48px; color: #ccc; line-height: 330px;">+</div>'; | |||
} | |||
} | |||
// 设置全局模态框监听器 | |||
function setupGlobalModalListener() { | |||
if (window.deckModalObserver) { | |||
window.deckModalObserver.disconnect(); | |||
} | |||
window.deckModalObserver = new MutationObserver(function(mutations) { | |||
mutations.forEach(function(mutation) { | |||
if (mutation.type === 'attributes' && mutation.attributeName === 'style') { | |||
var modal = mutation.target; | |||
if (modal.classList.contains('card-modal') && modal.style.display !== 'none') { | |||
setTimeout(function() { | |||
enhanceActiveModal(modal); | |||
}, 100); | |||
} | |||
} | |||
}); | |||
}); | |||
document.querySelectorAll('.card-modal').forEach(function(modal) { | |||
window.deckModalObserver.observe(modal, { | |||
attributes: true, | |||
attributeFilter: ['style'] | |||
}); | |||
}); | |||
} | |||
// 增强当前活动的模态框 | |||
function enhanceActiveModal(modal) { | |||
var cardId = modal.id ? modal.id.replace('-modal', '') : null; | |||
if (!cardId) return; | |||
var deckCard = null; | |||
var uniqueId = null; | |||
var unitIndex = null; | |||
document.querySelectorAll('.deck-area .deck-card-wrapper').forEach(function(wrapper) { | |||
var wrapperCard = wrapper.querySelector('.card-small-wrapper'); | |||
if (wrapperCard && wrapperCard.getAttribute('data-card-id') === cardId) { | |||
deckCard = wrapper; | |||
uniqueId = wrapper.getAttribute('data-unique-id'); | |||
unitIndex = wrapper.getAttribute('data-unit-index'); | |||
} | |||
}); | |||
if (!deckCard || !uniqueId || !unitIndex) { | |||
return; | |||
} | |||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | |||
if (!cardData) { | |||
return; | |||
} | |||
if (modal.hasAttribute('data-deck-enhanced')) { | |||
return; | |||
} | |||
modal.setAttribute('data-deck-enhanced', 'true'); | |||
var inspirationButton = modal.querySelector('.inspiration-button'); | |||
if (inspirationButton) { | |||
inspirationButton.addEventListener('click', function() { | |||
setTimeout(function() { | |||
enhanceInspirationView(modal, uniqueId, unitIndex); | |||
}, 100); | |||
}); | |||
} | |||
var godButton = modal.querySelector('.god-inspiration-button'); | |||
if (godButton) { | |||
godButton.addEventListener('click', function() { | |||
setTimeout(function() { | |||
enhanceGodView(modal, uniqueId, unitIndex); | |||
}, 100); | |||
}); | |||
} | |||
} | |||
// 关闭模态框并恢复滚动 | |||
function closeModalAndRestoreScroll(modal) { | |||
modal.style.display = 'none'; | |||
modal.removeAttribute('data-deck-enhanced'); | |||
document.body.style.overflow = ''; | |||
document.body.style.position = ''; | |||
document.documentElement.style.overflow = ''; | |||
document.body.classList.remove('modal-open'); | |||
document.documentElement.classList.remove('modal-open'); | |||
window.dispatchEvent(new Event('resize')); | |||
} | |||
// 增强灵光一闪视图 | |||
function enhanceInspirationView(modal, uniqueId, unitIndex) { | |||
var inspirationView = modal.querySelector('.inspiration-view'); | |||
if (!inspirationView) return; | |||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | |||
if (!cardData) return; | |||
var variants = inspirationView.querySelectorAll('.inspiration-variant'); | |||
variants.forEach(function(variant, index) { | |||
if (!variant.querySelector('.select-variant-btn')) { | |||
var selectBtn = document.createElement('div'); | |||
selectBtn.className = 'select-variant-btn'; | |||
selectBtn.innerHTML = '选择此变体'; | |||
selectBtn.style.cssText = 'margin-top:10px;padding:8px 15px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;font-size:14px;font-weight:bold;border-radius:6px;cursor:pointer;text-align:center;'; | |||
selectBtn.addEventListener('click', function() { | |||
replaceCard(uniqueId, unitIndex, '灵光一闪', index + 1); | |||
closeModalAndRestoreScroll(modal); | |||
}); | |||
variant.appendChild(selectBtn); | |||
} | |||
}); | |||
} | |||
// 增强神光一闪视图 | |||
function enhanceGodView(modal, uniqueId, unitIndex) { | |||
var godView = modal.querySelector('.god-inspiration-view'); | |||
if (!godView) return; | |||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | |||
if (!cardData) return; | |||
var godGroups = godView.querySelectorAll('.god-group'); | |||
godGroups.forEach(function(group) { | |||
var groupNameEl = group.querySelector('div[style*="color:#ffd36a"]'); | |||
if (!groupNameEl) return; | |||
var groupName = groupNameEl.textContent.trim(); | |||
var variants = group.querySelectorAll('.god-variant-card'); | |||
variants.forEach(function(variant, index) { | |||
if (!variant.querySelector('.select-variant-btn')) { | |||
var selectBtn = document.createElement('div'); | |||
selectBtn.className = 'select-variant-btn'; | |||
selectBtn.innerHTML = '选择'; | |||
selectBtn.style.cssText = 'margin-top:5px;padding:6px 12px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;font-size:12px;font-weight:bold;border-radius:4px;cursor:pointer;text-align:center;'; | |||
selectBtn.addEventListener('click', function() { | |||
replaceCard(uniqueId, unitIndex, '神光一闪', groupName, index + 1); | |||
closeModalAndRestoreScroll(modal); | |||
}); | |||
variant.appendChild(selectBtn); | |||
} | |||
}); | |||
}); | |||
} | |||
// 替换卡牌 | |||
function replaceCard(uniqueId, unitIndex, variantType, param1, param2) { | |||
var cardData = characterUnits[unitIndex].selectedCards[uniqueId]; | |||
if (!cardData) { | |||
console.error('找不到卡牌数据:', uniqueId); | |||
return; | |||
} | |||
var wrapper = document.querySelector('[data-unique-id="' + uniqueId + '"]'); | |||
if (!wrapper) { | |||
console.error('找不到卡牌容器:', uniqueId); | |||
return; | |||
} | |||
cardData.variantType = variantType; | |||
cardData.variantParam = param1; | |||
cardData.variantIndex = param2; | |||
var oldContent = wrapper.innerHTML; | |||
wrapper.innerHTML = '<div style="color:#999;padding:20px;">加载中...</div>'; | |||
var invokeText = '{{#invoke:卡牌|main|' + cardData.module + '|' + cardData.cardName; | |||
if (variantType === '灵光一闪') { | |||
invokeText += '|灵光一闪|' + param1; | |||
} else if (variantType === '神光一闪') { | |||
invokeText += '|神光一闪|' + param1 + '|' + param2; | |||
} | |||
invokeText += '}}'; | |||
var apiUrl = mw.util.wikiScript('api'); | |||
var params = { | |||
action: 'parse', | |||
format: 'json', | |||
text: invokeText, | |||
contentmodel: 'wikitext', | |||
disablelimitreport: true | |||
}; | |||
fetch(apiUrl + '?' + new URLSearchParams(params)) | |||
.then(response => response.json()) | |||
.then(data => { | |||
if (data.parse && data.parse.text) { | |||
wrapper.innerHTML = data.parse.text['*']; | |||
setTimeout(function() { | |||
var newCard = wrapper.querySelector('.card-small-wrapper'); | |||
if (newCard) { | |||
// 确保wrapper样式 | |||
wrapper.style.flexShrink = '0'; | |||
wrapper.style.display = 'inline-block'; | |||
var deleteBtn = document.createElement('div'); | |||
deleteBtn.className = 'card-delete-btn'; | |||
deleteBtn.innerHTML = '×'; | |||
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;'; | |||
deleteBtn.addEventListener('click', function(e) { | |||
e.stopPropagation(); | |||
wrapper.remove(); | |||
delete characterUnits[unitIndex].selectedCards[uniqueId]; | |||
checkAndShowPlaceholder(unitIndex); | |||
}); | |||
newCard.style.position = 'relative'; | |||
newCard.appendChild(deleteBtn); | |||
} | |||
setupGlobalModalListener(); | |||
document.body.style.overflow = ''; | |||
document.documentElement.style.overflow = ''; | |||
}, 100); | |||
} else { | |||
wrapper.innerHTML = oldContent; | |||
} | |||
}) | |||
.catch(error => { | |||
console.error('替换卡牌失败:', error); | |||
wrapper.innerHTML = oldContent; | |||
document.body.style.overflow = ''; | |||
document.documentElement.style.overflow = ''; | |||
}); | |||
} | |||
// 选择角色 | |||
document.getElementById('character-list').addEventListener('click', function(e) { | |||
var characterOption = e.target.closest('.character-option'); | |||
if (characterOption && currentActiveUnit) { | |||
var characterName = characterOption.getAttribute('data-character-name') || | |||
characterOption.getAttribute('data-name') || | |||
characterOption.getAttribute('title'); | |||
var characterClass = characterOption.getAttribute('data-class') || | |||
characterOption.getAttribute('data-职业'); | |||
if (!characterName) { | |||
var nameEl = characterOption.querySelector('.character-name, [class*="name"]'); | |||
if (nameEl) characterName = nameEl.textContent.trim(); | |||
} | |||
characterUnits[currentActiveUnit].characterClass = characterClass; | |||
var clonedCard = characterOption.cloneNode(true); | |||
clonedCard.classList.remove('character-option'); | |||
clonedCard.style.cursor = 'default'; | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]'); | |||
var characterSlot = unit.querySelector('.character-slot'); | |||
characterSlot.innerHTML = ''; | |||
characterSlot.appendChild(clonedCard); | |||
characterSlot.style.border = 'none'; | |||
document.getElementById('character-modal').style.display = 'none'; | |||
if (characterName) { | |||
loadCharacterCards(characterName, currentActiveUnit); | |||
} | |||
} | |||
}); | |||
// 选择伙伴 | |||
document.querySelectorAll('.partner-slot').forEach(function(slot) { | |||
slot.addEventListener('click', function() { | |||
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index'); | |||
document.getElementById('partner-modal').style.display = 'block'; | |||
}); | |||
}); | |||
document.getElementById('close-partner-modal').addEventListener('click', function() { | |||
document.getElementById('partner-modal').style.display = 'none'; | |||
}); | |||
document.getElementById('partner-modal').addEventListener('click', function(e) { | |||
if (e.target === this) { | |||
this.style.display = 'none'; | |||
} | |||
}); | |||
document.getElementById('partner-list').addEventListener('click', function(e) { | |||
var partnerOption = e.target.closest('.partner-option'); | |||
if (partnerOption && currentActiveUnit) { | |||
var partnerId = partnerOption.dataset.partnerId || partnerOption.getAttribute('data-partner-id'); | |||
var partnerImg = document.createElement('img'); | |||
partnerImg.src = '/index.php?title=Special:Redirect/file/Portrait_character_wide_' + partnerId + '.png'; | |||
partnerImg.style.width = '159px'; | |||
partnerImg.style.height = '77px'; | |||
partnerImg.style.objectFit = 'cover'; | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]'); | |||
var partnerSlot = unit.querySelector('.partner-slot'); | |||
partnerSlot.innerHTML = ''; | |||
partnerSlot.appendChild(partnerImg); | |||
partnerSlot.style.border = 'none'; | |||
document.getElementById('partner-modal').style.display = 'none'; | |||
} | |||
}); | |||
// ========== 卡牌添加功能 ========== | |||
var currentDeckArea = null; | |||
var currentCardType = 'character'; | |||
// 点击卡组区域打开卡牌选择 | |||
document.querySelectorAll('.deck-area').forEach(function(deckArea) { | |||
var originalClickHandler = function(e) { | |||
if (e.target.closest('.deck-card-wrapper') || | |||
e.target.closest('.card-small-wrapper') || | |||
e.target.closest('.card-delete-btn') || | |||
e.target.classList.contains('card-delete-btn')) { | |||
return; | |||
} | |||
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index'); | |||
currentDeckArea = this; | |||
var unit = this.closest('.character-unit'); | |||
var characterSlot = unit.querySelector('.character-slot'); | |||
var hasCharacter = characterSlot.querySelector('img') !== null || | |||
characterSlot.innerHTML.indexOf('data-character-name') > -1 || | |||
!characterSlot.querySelector('.placeholder'); | |||
var unitData = characterUnits[currentActiveUnit]; | |||
if (!unitData.characterName) { | |||
hasCharacter = false; | |||
} | |||
if (!hasCharacter) { | |||
alert('请先选择战斗员!'); | |||
return; | |||
} | |||
currentCardType = 'character'; | |||
document.querySelectorAll('.card-type-tab').forEach(function(tab) { | |||
tab.classList.remove('active'); | |||
tab.style.borderBottomColor = 'transparent'; | |||
tab.style.fontWeight = 'normal'; | |||
}); | |||
var characterTab = document.querySelector('.card-type-tab[data-type="character"]'); | |||
if (characterTab) { | |||
characterTab.classList.add('active'); | |||
characterTab.style.borderBottomColor = '#667eea'; | |||
characterTab.style.fontWeight = 'bold'; | |||
} | |||
document.getElementById('card-modal').style.display = 'block'; | |||
loadCardList('character'); | |||
}; | |||
deckArea.addEventListener('click', originalClickHandler); | |||
}); | |||
// 卡牌类型标签切换 | |||
document.querySelectorAll('.card-type-tab').forEach(function(tab) { | |||
tab.addEventListener('click', function() { | |||
var cardType = this.getAttribute('data-type'); | |||
currentCardType = cardType; | |||
document.querySelectorAll('.card-type-tab').forEach(function(t) { | |||
t.classList.remove('active'); | |||
t.style.borderBottomColor = 'transparent'; | |||
t.style.fontWeight = 'normal'; | |||
}); | |||
this.classList.add('active'); | |||
this.style.borderBottomColor = '#667eea'; | |||
this.style.fontWeight = 'bold'; | |||
loadCardList(cardType); | |||
}); | |||
}); | |||
// 加载卡牌列表 | |||
function loadCardList(cardType) { | |||
var listContainer = document.getElementById('card-selection-list'); | |||
listContainer.innerHTML = '<div style="color:#999;font-size:18px;">加载中...</div>'; | |||
var apiUrl = mw.util.wikiScript('api'); | |||
var invokeText = ''; | |||
if (cardType === 'character') { | |||
var unitData = characterUnits[currentActiveUnit]; | |||
if (!unitData.characterName) { | |||
listContainer.innerHTML = '<div style="color:red;">错误: 未选择战斗员</div>'; | |||
return; | |||
} | |||
invokeText = '{{#invoke:配队/卡牌|deck|' + unitData.characterName + '}}'; | |||
} else if (cardType === 'neutral') { | |||
var unitData = characterUnits[currentActiveUnit]; | |||
var characterClass = unitData.characterClass; | |||
if (characterClass) { | |||
invokeText = '{{#invoke:卡牌/中立|showByClass|' + characterClass + '}}'; | |||
} else { | |||
invokeText = '{{#invoke:卡牌/中立|showAll}}'; | |||
} | |||
} else if (cardType === 'monster') { | |||
invokeText = '{{#invoke:卡牌/怪物|all}}'; | |||
} | |||
var params = { | |||
action: 'parse', | |||
format: 'json', | |||
text: invokeText, | |||
contentmodel: 'wikitext', | |||
disablelimitreport: true, | |||
wrapoutputclass: '' | |||
}; | |||
fetch(apiUrl + '?' + new URLSearchParams(params)) | |||
.then(response => response.json()) | |||
.then(data => { | |||
if (data.parse && data.parse.text) { | |||
listContainer.innerHTML = data.parse.text['*']; | |||
setTimeout(function() { | |||
addCardSelectionHandlers(cardType); | |||
}, 100); | |||
} else { | |||
listContainer.innerHTML = '<div style="color:red;">加载卡牌失败</div>'; | |||
} | |||
}) | |||
.catch(error => { | |||
console.error('加载卡牌失败:', error); | |||
listContainer.innerHTML = '<div style="color:red;">加载卡牌出错:' + error.message + '</div>'; | |||
}); | |||
} | |||
// 添加卡牌选择处理器 | |||
function addCardSelectionHandlers(cardType) { | |||
var listContainer = document.getElementById('card-selection-list'); | |||
if (cardType === 'character') { | |||
var wrappers = listContainer.querySelectorAll('.deck-card-wrapper'); | |||
wrappers.forEach(function(wrapper) { | |||
wrapper.style.cursor = 'pointer'; | |||
wrapper.style.transition = 'transform 0.2s'; | |||
wrapper.addEventListener('mouseenter', function() { | |||
this.style.transform = 'scale(1.05)'; | |||
}); | |||
wrapper.addEventListener('mouseleave', function() { | |||
this.style.transform = 'scale(1)'; | |||
}); | |||
wrapper.addEventListener('click', function(e) { | |||
e.stopPropagation(); | |||
var cardName = this.getAttribute('data-card'); | |||
var card = this.querySelector('.card-small-wrapper'); | |||
if (!cardName && card) { | |||
cardName = card.getAttribute('data-card'); | |||
} | |||
if (!cardName) { | |||
console.error('无法获取卡牌名称'); | |||
return; | |||
} | |||
var hasInspiration = card && card.querySelector('.inspiration-button'); | |||
var hasGodInspiration = card && card.querySelector('.god-inspiration-button'); | |||
if (hasInspiration || hasGodInspiration) { | |||
showVariantSelectionDialog(cardName, 'character'); | |||
} else { | |||
addCardToDeckByName(cardName, 'character'); | |||
} | |||
}); | |||
}); | |||
} else { | |||
var cards = listContainer.querySelectorAll('.card-small-wrapper'); | |||
cards.forEach(function(card) { | |||
card.style.cursor = 'pointer'; | |||
card.style.transition = 'transform 0.2s'; | |||
card.addEventListener('mouseenter', function() { | |||
this.style.transform = 'scale(1.05)'; | |||
}); | |||
card.addEventListener('mouseleave', function() { | |||
this.style.transform = 'scale(1)'; | |||
}); | |||
card.addEventListener('click', function(e) { | |||
e.stopPropagation(); | |||
addCardToDeck(this, cardType); | |||
}); | |||
}); | |||
} | |||
} | |||
// 显示变体选择对话框 | |||
function showVariantSelectionDialog(cardName, cardType) { | |||
var dialog = document.createElement('div'); | |||
dialog.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:30px;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,0.3);z-index:10001;min-width:300px;'; | |||
var html = '<h3 style="margin:0 0 20px 0;color:#667eea;text-align:center;">选择添加方式</h3>'; | |||
html += '<p style="margin:0 0 20px 0;color:#666;text-align:center;">卡牌: ' + cardName + '</p>'; | |||
html += '<div style="display:flex;flex-direction:column;gap:0px;">'; | |||
html += '<div class="variant-option-btn" data-action="base" style="padding:12px 20px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:white;border-radius:8px;cursor:pointer;text-align:center;font-weight:bold;transition:all 0.3s;">添加基础卡牌</div>'; | |||
html += '<div class="variant-option-btn" data-action="view" style="padding:12px 20px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;border-radius:8px;cursor:pointer;text-align:center;font-weight:bold;transition:all 0.3s;">查看变体并选择</div>'; | |||
html += '<div class="variant-option-btn" data-action="cancel" style="padding:12px 20px;background:#ccc;color:#333;border-radius:8px;cursor:pointer;text-align:center;font-weight:bold;transition:all 0.3s;">取消</div>'; | |||
html += '</div>'; | |||
dialog.innerHTML = html; | |||
var overlay = document.createElement('div'); | |||
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:10000;'; | |||
document.body.appendChild(overlay); | |||
document.body.appendChild(dialog); | |||
dialog.querySelectorAll('.variant-option-btn').forEach(function(btn) { | |||
btn.addEventListener('mouseenter', function() { | |||
this.style.transform = 'translateY(-2px)'; | |||
this.style.boxShadow = '0 5px 15px rgba(0,0,0,0.2)'; | |||
}); | |||
btn.addEventListener('mouseleave', function() { | |||
this.style.transform = 'translateY(0)'; | |||
this.style.boxShadow = 'none'; | |||
}); | |||
}); | |||
dialog.addEventListener('click', function(e) { | |||
var btn = e.target.closest('.variant-option-btn'); | |||
if (!btn) return; | |||
var action = btn.getAttribute('data-action'); | |||
if (action === 'base') { | |||
addCardToDeckByName(cardName, cardType); | |||
document.body.removeChild(overlay); | |||
document.body.removeChild(dialog); | |||
document.getElementById('card-modal').style.display = 'none'; | |||
} else if (action === 'view') { | |||
addCardToDeckByName(cardName, cardType, function() { | |||
document.body.removeChild(overlay); | |||
document.body.removeChild(dialog); | |||
document.getElementById('card-modal').style.display = 'none'; | |||
setTimeout(function() { | |||
alert('卡牌已添加!现在您可以点击卡牌查看并选择变体。'); | |||
}, 300); | |||
}); | |||
} else { | |||
document.body.removeChild(overlay); | |||
document.body.removeChild(dialog); | |||
} | |||
}); | |||
} | |||
// 按名称添加卡牌到卡组 | |||
function addCardToDeckByName(cardName, cardType, callback) { | |||
if (!currentDeckArea || !currentActiveUnit) return; | |||
var unitData = characterUnits[currentActiveUnit]; | |||
var moduleName = ''; | |||
if (cardType === 'character') { | |||
moduleName = unitData.characterName; | |||
} else if (cardType === 'neutral') { | |||
moduleName = '中立'; | |||
} else if (cardType === 'monster') { | |||
moduleName = '怪物'; | |||
} | |||
var invokeText = ''; | |||
if (cardType === 'character') { | |||
invokeText = '{{#invoke:卡牌|main|' + moduleName + '|' + cardName + '}}'; | |||
} else if (cardType === 'neutral') { | |||
invokeText = '{{#invoke:卡牌/中立|main|' + cardName + '}}'; | |||
} else if (cardType === 'monster') { | |||
invokeText = '{{#invoke:卡牌/怪物|main|' + cardName + '}}'; | |||
} | |||
var apiUrl = mw.util.wikiScript('api'); | |||
var params = { | |||
action: 'parse', | |||
format: 'json', | |||
text: invokeText, | |||
contentmodel: 'wikitext', | |||
disablelimitreport: true | |||
}; | |||
fetch(apiUrl + '?' + new URLSearchParams(params)) | |||
.then(response => response.json()) | |||
.then(data => { | |||
if (data.parse && data.parse.text) { | |||
// 移除占位符 | |||
var placeholder = currentDeckArea.querySelector('.deck-placeholder'); | |||
if (placeholder) { | |||
placeholder.remove(); | |||
} | |||
var wrapper = document.createElement('div'); | |||
wrapper.className = 'deck-card-wrapper'; | |||
wrapper.innerHTML = data.parse.text['*']; | |||
wrapper.setAttribute('data-module', moduleName); | |||
wrapper.setAttribute('data-card', cardName); | |||
// 确保wrapper不会换行 | |||
wrapper.style.flexShrink = '0'; | |||
wrapper.style.display = 'inline-block'; | |||
var uniqueId = 'deck-card-' + currentActiveUnit + '-' + (++unitData.cardIdCounter); | |||
wrapper.setAttribute('data-unique-id', uniqueId); | |||
wrapper.setAttribute('data-unit-index', currentActiveUnit); | |||
unitData.selectedCards[uniqueId] = { | |||
module: moduleName, | |||
cardName: cardName, | |||
variantType: null, | |||
variantParam: null, | |||
variantIndex: null | |||
}; | |||
currentDeckArea.appendChild(wrapper); | |||
setTimeout(function() { | |||
var card = wrapper.querySelector('.card-small-wrapper'); | |||
if (card) { | |||
var deleteBtn = document.createElement('div'); | |||
deleteBtn.className = 'card-delete-btn'; | |||
deleteBtn.innerHTML = '×'; | |||
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;'; | |||
deleteBtn.addEventListener('click', function(e) { | |||
e.stopPropagation(); | |||
wrapper.remove(); | |||
delete unitData.selectedCards[uniqueId]; | |||
checkAndShowPlaceholder(currentActiveUnit); | |||
}); | |||
card.style.position = 'relative'; | |||
card.appendChild(deleteBtn); | |||
} | |||
setupGlobalModalListener(); | |||
if (callback) callback(); | |||
}, 100); | |||
} else { | |||
alert('添加卡牌失败'); | |||
} | |||
}) | |||
.catch(error => { | |||
console.error('添加卡牌失败:', error); | |||
alert('添加卡牌出错:' + error.message); | |||
}); | |||
} | |||
// 添加卡牌到卡组(从元素获取信息) | |||
function addCardToDeck(cardElement, cardType) { | |||
if (!currentDeckArea || !currentActiveUnit) return; | |||
var cardName = cardElement.getAttribute('data-card-name') || | |||
cardElement.getAttribute('data-card'); | |||
if (!cardName) { | |||
var parent = cardElement.closest('[data-card]'); | |||
if (parent) { | |||
cardName = parent.getAttribute('data-card'); | |||
} | |||
} | |||
if (!cardName) { | |||
var parent = cardElement.closest('[data-card-name]'); | |||
if (parent) { | |||
cardName = parent.getAttribute('data-card-name'); | |||
} | |||
} | |||
if (!cardName) { | |||
var wrapper = cardElement.closest('.deck-card-wrapper'); | |||
if (wrapper) { | |||
cardName = wrapper.getAttribute('data-card'); | |||
} | |||
} | |||
if (!cardName) { | |||
console.error('无法获取卡牌名称'); | |||
alert('错误:无法获取卡牌名称'); | |||
return; | |||
} | |||
addCardToDeckByName(cardName, cardType, function() { | |||
document.getElementById('card-modal').style.display = 'none'; | |||
}); | |||
} | |||
// 关闭卡牌选择窗口 | |||
document.getElementById('close-card-modal').addEventListener('click', function() { | |||
document.getElementById('card-modal').style.display = 'none'; | |||
}); | |||
document.getElementById('card-modal').addEventListener('click', function(e) { | |||
if (e.target === this) { | |||
this.style.display = 'none'; | |||
} | |||
}); | |||
// ========== 装备选择功能 ========== | |||
document.querySelectorAll('.equipment-slot').forEach(function(slot) { | |||
slot.addEventListener('click', function() { | |||
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index'); | |||
var equipmentType = this.getAttribute('data-equipment-type'); | |||
var titleMap = { | |||
'weapon': '选择武器', | |||
'armor': '选择装甲', | |||
'ring': '选择戒指' | |||
}; | |||
document.getElementById('equipment-modal-title').textContent = titleMap[equipmentType] || '选择装备'; | |||
loadEquipmentList(equipmentType); | |||
document.getElementById('equipment-modal').style.display = 'block'; | |||
}); | |||
}); | |||
document.getElementById('close-equipment-modal').addEventListener('click', function() { | |||
document.getElementById('equipment-modal').style.display = 'none'; | |||
}); | |||
document.getElementById('equipment-modal').addEventListener('click', function(e) { | |||
if (e.target === this) { | |||
this.style.display = 'none'; | |||
} | |||
}); | |||
function loadEquipmentList(equipmentType) { | |||
var listContainer = document.getElementById('equipment-list'); | |||
listContainer.innerHTML = '<div style="color:#999;font-size:18px;">加载中...</div>'; | |||
var categoryMap = { | |||
'weapon': '武器', | |||
'armor': '装甲', | |||
'ring': '戒指' | |||
}; | |||
var category = categoryMap[equipmentType]; | |||
var apiUrl = mw.util.wikiScript('api'); | |||
var askQuery = '{{#ask:[[分类:' + category + ']]|?名称|?稀有度|sort=稀有度,名称|order=desc,asc|format=template|template=配队/装备|limit=500}}'; | |||
var params = { | |||
action: 'parse', | |||
format: 'json', | |||
text: askQuery, | |||
contentmodel: 'wikitext', | |||
disablelimitreport: true | |||
}; | |||
fetch(apiUrl + '?' + new URLSearchParams(params)) | |||
.then(response => response.json()) | |||
.then(data => { | |||
if (data.parse && data.parse.text) { | |||
listContainer.innerHTML = data.parse.text['*']; | |||
setTimeout(function() { | |||
addEquipmentSelectionHandlers(equipmentType); | |||
}, 100); | |||
} else { | |||
listContainer.innerHTML = '<div style="color:red;">加载装备失败</div>'; | |||
} | |||
}) | |||
.catch(error => { | |||
console.error('加载装备失败:', error); | |||
listContainer.innerHTML = '<div style="color:red;">加载装备出错:' + error.message + '</div>'; | |||
}); | |||
} | |||
function addEquipmentSelectionHandlers(equipmentType) { | |||
var equipmentOptions = document.querySelectorAll('#equipment-list .equipment-option'); | |||
equipmentOptions.forEach(function(option) { | |||
option.style.cursor = 'pointer'; | |||
option.style.transition = 'all 0.3s'; | |||
option.addEventListener('mouseenter', function() { | |||
this.style.transform = 'translateY(-5px)'; | |||
this.style.boxShadow = '0 5px 20px rgba(102,126,234,0.4)'; | |||
}); | |||
option.addEventListener('mouseleave', function() { | |||
this.style.transform = 'translateY(0)'; | |||
this.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)'; | |||
}); | |||
option.addEventListener('click', function() { | |||
var equipmentId = this.getAttribute('data-equipment-id'); | |||
var equipmentImg = this.querySelector('img'); | |||
if (equipmentImg && currentActiveUnit) { | |||
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]'); | |||
var slot = unit.querySelector('.equipment-slot[data-equipment-type="' + equipmentType + '"]'); | |||
var clonedImg = equipmentImg.cloneNode(true); | |||
clonedImg.style.width = '100px'; | |||
clonedImg.style.height = '100px'; | |||
clonedImg.style.objectFit = 'contain'; | |||
slot.innerHTML = ''; | |||
slot.appendChild(clonedImg); | |||
slot.style.border = 'none'; | |||
document.getElementById('equipment-modal').style.display = 'none'; | |||
} | |||
}); | |||
}); | |||
} | |||
// 初始化:设置默认角色1为激活单元 | |||
currentActiveUnit = '0'; | |||
} | |||
// 页面加载完成后初始化 | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', initTeamSimulator); | |||
} else { | |||
initTeamSimulator(); | |||
} | |||
})(); | |||
</script> | |||
<style> | |||
#team-simulator { | |||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; | |||
} | |||
#save-team-btn:hover { | |||
transform: translateY(-2px); | |||
box-shadow: 0 6px 12px rgba(0,0,0,0.15); | |||
} | |||
#save-team-btn:active { | |||
transform: translateY(0); | |||
} | |||
.character-unit { | |||
background: white; | |||
transition: all 0.3s; | |||
} | |||
.character-slot, .partner-slot { | |||
transition: all 0.3s; | |||
overflow: hidden; | |||
} | |||
.character-slot:hover, .partner-slot:hover { | |||
border-color: #667eea; | |||
background: #f9f9ff; | |||
} | |||
.deck-area { | |||
transition: border-color 0.3s, background 0.3s; | |||
} | |||
.deck-area:hover { | |||
border-color: #667eea; | |||
} | |||
/* 确保卡牌wrapper不换行 */ | |||
.deck-card-wrapper { | |||
flex-shrink: 0; | |||
display: inline-block; | |||
} | |||
/* 确保中立和怪物卡牌也不换行 */ | |||
#card-selection-list .deck-card-wrapper, | |||
#card-selection-list .card-small-wrapper { | |||
flex-shrink: 0; | |||
display: inline-block; | |||
} | |||
.equipment-slot { | |||
transition: all 0.3s; | |||
} | |||
.equipment-slot:hover { | |||
border-color: #667eea; | |||
background: #f9f9ff; | |||
} | |||
/* 模态框样式优化 */ | |||
#card-modal, #character-modal, #partner-modal, #equipment-modal { | |||
animation: fadeIn 0.3s ease; | |||
} | |||
@keyframes fadeIn { | |||
from { | |||
opacity: 0; | |||
} | |||
to { | |||
opacity: 1; | |||
} | |||
} | |||
/* 模态框内容动画 */ | |||
#card-modal > div, | |||
#character-modal > div, | |||
#partner-modal > div, | |||
#equipment-modal > div { | |||
animation: slideIn 0.3s ease; | |||
} | |||
@keyframes slideIn { | |||
from { | |||
transform: translate(-50%, -60%); | |||
opacity: 0; | |||
} | |||
to { | |||
transform: translate(-50%, -50%); | |||
opacity: 1; | |||
} | |||
} | |||
/* 卡牌类型标签样式 */ | |||
.card-type-tab { | |||
transition: all 0.3s; | |||
} | |||
.card-type-tab:hover { | |||
color: #667eea; | |||
background: rgba(102, 126, 234, 0.05); | |||
} | |||
.card-type-tab.active { | |||
color: #667eea; | |||
} | |||
/* 角色和伙伴选项样式 */ | |||
.character-option, .partner-option { | |||
transition: all 0.3s; | |||
} | |||
.character-option:hover, .partner-option:hover { | |||
transform: translateY(-5px); | |||
box-shadow: 0 5px 20px rgba(102,126,234,0.4); | |||
} | |||
/* 装备选项样式 */ | |||
.equipment-option { | |||
cursor: pointer; | |||
padding: 10px; | |||
border: 2px solid transparent; | |||
border-radius: 8px; | |||
transition: all 0.3s; | |||
background: white; | |||
} | |||
.equipment-option:hover { | |||
border-color: #667eea; | |||
transform: translateY(-5px); | |||
box-shadow: 0 5px 20px rgba(102,126,234,0.4); | |||
} | |||
/* 删除按钮样式优化 */ | |||
.card-delete-btn { | |||
transition: all 0.2s; | |||
user-select: none; | |||
} | |||
.card-delete-btn:hover { | |||
background: rgba(255,0,0,0.9); | |||
transform: scale(1.2); | |||
} | |||
/* 占位符样式 */ | |||
.deck-placeholder { | |||
pointer-events: none; | |||
user-select: none; | |||
} | |||
/* 变体选择按钮样式 */ | |||
.select-variant-btn { | |||
transition: all 0.3s; | |||
user-select: none; | |||
} | |||
.select-variant-btn:hover { | |||
transform: translateY(-2px); | |||
box-shadow: 0 5px 15px rgba(0,0,0,0.2); | |||
} | |||
.select-variant-btn:active { | |||
transform: translateY(0); | |||
} | |||
/* 卡牌选择列表样式优化 */ | |||
#card-selection-list { | |||
max-height: 60vh; | |||
overflow-y: auto; | |||
} | |||
/* 自定义滚动条 */ | |||
#card-selection-list::-webkit-scrollbar, | |||
#character-list::-webkit-scrollbar, | |||
#partner-list::-webkit-scrollbar, | |||
#equipment-list::-webkit-scrollbar { | |||
width: 8px; | |||
} | |||
#card-selection-list::-webkit-scrollbar-track, | |||
#character-list::-webkit-scrollbar-track, | |||
#partner-list::-webkit-scrollbar-track, | |||
#equipment-list::-webkit-scrollbar-track { | |||
background: #f1f1f1; | |||
border-radius: 4px; | |||
} | |||
#card-selection-list::-webkit-scrollbar-thumb, | |||
#character-list::-webkit-scrollbar-thumb, | |||
#partner-list::-webkit-scrollbar-thumb, | |||
#equipment-list::-webkit-scrollbar-thumb { | |||
background: #888; | |||
border-radius: 4px; | |||
} | |||
#card-selection-list::-webkit-scrollbar-thumb:hover, | |||
#character-list::-webkit-scrollbar-thumb:hover, | |||
#partner-list::-webkit-scrollbar-thumb:hover, | |||
#equipment-list::-webkit-scrollbar-thumb:hover { | |||
background: #555; | |||
} | |||
/* 响应式设计 */ | |||
@media (max-width: 1200px) { | |||
#team-content { | |||
max-width: 100%; | |||
padding: 10px; | |||
} | |||
.character-unit { | |||
padding: 15px; | |||
} | |||
} | |||
@media (max-width: 768px) { | |||
.character-unit > div { | |||
flex-direction: column; | |||
} | |||
.character-unit > div > div { | |||
width: 100% !important; | |||
} | |||
.deck-area { | |||
min-height: 200px; | |||
} | |||
#card-modal > div, | |||
#character-modal > div, | |||
#partner-modal > div, | |||
#equipment-modal > div { | |||
width: 95%; | |||
max-width: 95%; | |||
min-width: auto; | |||
padding: 15px; | |||
} | |||
.card-type-tab { | |||
padding: 8px 12px; | |||
font-size: 14px; | |||
} | |||
#save-team-btn { | |||
padding: 10px 20px; | |||
font-size: 14px; | |||
} | } | ||
} | |||
/* 卡牌hover效果 */ | |||
.deck-card-wrapper:hover { | |||
z-index: 10; | |||
} | |||
.card-small-wrapper { | |||
transition: transform 0.2s; | |||
} | |||
.deck-card-wrapper:hover .card-small-wrapper { | |||
transform: scale(1.05); | |||
} | |||
/* 加载动画 */ | |||
@keyframes spin { | |||
0% { transform: rotate(0deg); } | |||
100% { transform: rotate(360deg); } | |||
} | |||
/* 关闭按钮样式 */ | |||
#close-card-modal, | |||
#close-character-modal, | |||
#close-partner-modal, | |||
#close-equipment-modal { | |||
transition: all 0.3s; | |||
user-select: none; | |||
} | |||
#close-card-modal:hover, | |||
#close-character-modal:hover, | |||
#close-partner-modal:hover, | |||
#close-equipment-modal:hover { | |||
color: #ff6b6b; | |||
transform: rotate(90deg) scale(1.2); | |||
} | |||
/* 变体对话框按钮动画 */ | |||
.variant-option-btn { | |||
position: relative; | |||
overflow: hidden; | |||
} | |||
.variant-option-btn::before { | |||
content: ''; | |||
position: absolute; | |||
top: 50%; | |||
left: 50%; | |||
width: 0; | |||
height: 0; | |||
border-radius: 50%; | |||
background: rgba(255,255,255,0.3); | |||
transform: translate(-50%, -50%); | |||
transition: width 0.6s, height 0.6s; | |||
} | |||
.variant-option-btn:hover::before { | |||
width: 300px; | |||
height: 300px; | |||
} | |||
/* 确保弹窗内容居中 */ | |||
#card-modal > div, | |||
#character-modal > div, | |||
#partner-modal > div, | |||
#equipment-modal > div { | |||
box-sizing: border-box; | |||
} | |||
/* 网格布局优化 */ | |||
#character-list, | |||
#partner-list { | |||
display: grid; | |||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); | |||
gap: 15px; | |||
justify-items: center; | |||
} | |||
#equipment-list { | |||
display: grid; | |||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); | |||
gap: 15px; | |||
justify-items: center; | |||
} | |||
/* 图片加载优化 */ | |||
img { | |||
image-rendering: -webkit-optimize-contrast; | |||
} | |||
/* 防止文本选择 */ | |||
.character-slot, | |||
.partner-slot, | |||
.deck-area, | |||
.equipment-slot, | |||
.card-type-tab, | |||
#save-team-btn { | |||
user-select: none; | |||
-webkit-user-select: none; | |||
-moz-user-select: none; | |||
-ms-user-select: none; | |||
} | |||
/* 工具提示样式(如果需要) */ | |||
[data-tooltip] { | |||
position: relative; | |||
} | |||
[data-tooltip]::after { | |||
content: attr(data-tooltip); | |||
position: absolute; | |||
bottom: 100%; | |||
left: 50%; | |||
transform: translateX(-50%); | |||
padding: 5px 10px; | |||
background: rgba(0,0,0,0.8); | |||
color: white; | |||
border-radius: 4px; | |||
font-size: 12px; | |||
white-space: nowrap; | |||
opacity: 0; | |||
pointer-events: none; | |||
transition: opacity 0.3s; | |||
} | |||
[data-tooltip]:hover::after { | |||
opacity: 1; | |||
} | |||
/* 确保deck-area内的flex布局正确 */ | |||
.deck-area { | |||
box-sizing: border-box; | |||
} | |||
.deck-area > * { | |||
box-sizing: border-box; | |||
} | |||
/* 修复可能的布局问题 */ | |||
.character-unit > div { | |||
box-sizing: border-box; | |||
} | |||
.character-unit > div > div { | |||
box-sizing: border-box; | |||
} | |||
/* 打印样式优化 */ | |||
@media print { | |||
#save-team-btn, | |||
.card-delete-btn, | |||
#card-modal, | |||
#character-modal, | |||
#partner-modal, | |||
#equipment-modal { | |||
display: none !important; | |||
} | |||
.character-unit { | |||
page-break-inside: avoid; | |||
} | } | ||
} | |||
/* 无障碍支持 */ | |||
button, [role="button"], .character-option, .partner-option, .equipment-option, .card-type-tab { | |||
outline-offset: 2px; | |||
} | |||
button:focus, [role="button"]:focus, .character-option:focus, .partner-option:focus, .equipment-option:focus, .card-type-tab:focus { | |||
outline: 2px solid #667eea; | |||
} | |||
/* 暗色模式支持(如果需要) */ | |||
</ | @media (prefers-color-scheme: dark) { | ||
/* 可以在这里添加暗色模式样式 */ | |||
} | |||
</style> | |||
2025年11月1日 (六) 16:43的最新版本
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<script> (function() {
// 等待DOM加载完成
function initTeamSimulator() {
// 为每个角色单元保存独立的状态
var characterUnits = {};
var currentActiveUnit = null;
// 初始化所有角色单元
document.querySelectorAll('.character-unit').forEach(function(unit) {
var unitIndex = unit.getAttribute('data-unit-index');
characterUnits[unitIndex] = {
characterName: null,
characterClass: null,
cardIdCounter: 0,
selectedCards: {}
};
});
// ========== 保存为图片功能 ==========
document.getElementById('save-team-btn').addEventListener('click', function() {
var btn = this;
var originalText = btn.textContent;
btn.textContent = '生成中...';
btn.style.pointerEvents = 'none';
var contentElement = document.getElementById('team-content');
// 临时隐藏删除按钮
var deleteButtons = contentElement.querySelectorAll('.card-delete-btn');
deleteButtons.forEach(function(btn) {
btn.style.display = 'none';
});
html2canvas(contentElement, {
backgroundColor: '#ffffff',
scale: 2,
logging: false,
useCORS: true,
allowTaint: true
}).then(function(canvas) {
// 恢复删除按钮
deleteButtons.forEach(function(btn) {
btn.style.display = 'flex';
});
// 下载图片
var link = document.createElement('a');
link.download = '配队方案_' + new Date().getTime() + '.png';
link.href = canvas.toDataURL('image/png');
link.click();
btn.textContent = originalText;
btn.style.pointerEvents = 'auto';
}).catch(function(error) {
console.error('保存失败:', error);
alert('保存失败,请重试');
// 恢复删除按钮
deleteButtons.forEach(function(btn) {
btn.style.display = 'flex';
});
btn.textContent = originalText;
btn.style.pointerEvents = 'auto';
});
});
// 点击角色槽位显示选择窗口
document.querySelectorAll('.character-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
document.getElementById('character-modal').style.display = 'block';
});
});
// 关闭角色选择窗口
document.getElementById('close-character-modal').addEventListener('click', function() {
document.getElementById('character-modal').style.display = 'none';
});
// 点击遮罩层关闭窗口
document.getElementById('character-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
// 加载战斗员卡牌 - 支持多角色
function loadCharacterCards(characterName, unitIndex) {
if (!characterName) {
console.error('战斗员名称为空');
return;
}
var unitData = characterUnits[unitIndex];
unitData.characterName = characterName;
console.log('加载战斗员卡牌:', characterName, '单元:', unitIndex);
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var deckArea = unit.querySelector('.deck-area');
// 显示加载状态
var placeholder = deckArea.querySelector('.deck-placeholder');
if (placeholder) {
placeholder.textContent = '加载中...';
placeholder.style.fontSize = '18px';
placeholder.style.color = '#999';
}
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: '错误: 找不到模块 "Module:卡牌/' + characterName + '"',
contentmodel: 'wikitext',
disablelimitreport: true,
wrapoutputclass:
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
// 清空并添加卡牌
deckArea.innerHTML = data.parse.text['*'];
// 重置该单元的卡牌状态
unitData.selectedCards = {};
unitData.cardIdCounter = 0;
setTimeout(function() {
initializeCardFeatures(unitIndex);
}, 100);
} else {
if (placeholder) {
placeholder.textContent = '加载失败';
placeholder.style.color = 'red';
}
}
})
.catch(error => {
console.error('加载卡牌失败:', error);
if (placeholder) {
placeholder.textContent = '加载出错';
placeholder.style.color = 'red';
}
});
}
// 初始化卡牌功能
function initializeCardFeatures(unitIndex) {
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var unitData = characterUnits[unitIndex];
var deckArea = unit.querySelector('.deck-area');
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper');
wrappers.forEach(function(wrapper) {
var card = wrapper.querySelector('.card-small-wrapper');
if (!card) return;
// 确保wrapper样式正确
wrapper.style.flexShrink = '0';
wrapper.style.display = 'inline-block';
var uniqueId = 'deck-card-' + unitIndex + '-' + (++unitData.cardIdCounter);
wrapper.setAttribute('data-unique-id', uniqueId);
wrapper.setAttribute('data-unit-index', unitIndex);
unitData.selectedCards[uniqueId] = {
module: wrapper.getAttribute('data-module') || unitData.characterName,
cardName: wrapper.getAttribute('data-card'),
variantType: null,
variantParam: null,
variantIndex: null
};
if (!card.querySelector('.card-delete-btn')) {
var deleteBtn = document.createElement('div');
deleteBtn.className = 'card-delete-btn';
deleteBtn.innerHTML = '×';
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;';
deleteBtn.addEventListener('click', function(e) {
e.stopPropagation();
wrapper.remove();
delete unitData.selectedCards[uniqueId];
// 如果没有卡牌了,显示占位符
checkAndShowPlaceholder(unitIndex);
});
card.style.position = 'relative';
card.appendChild(deleteBtn);
}
});
setupGlobalModalListener();
}
// 检查并显示占位符
function checkAndShowPlaceholder(unitIndex) {
var unit = document.querySelector('.character-unit[data-unit-index="' + unitIndex + '"]');
var deckArea = unit.querySelector('.deck-area');
var wrappers = deckArea.querySelectorAll('.deck-card-wrapper');
if (wrappers.length === 0) {
deckArea.innerHTML = '
';
}
}
// 设置全局模态框监听器
function setupGlobalModalListener() {
if (window.deckModalObserver) {
window.deckModalObserver.disconnect();
}
window.deckModalObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
var modal = mutation.target;
if (modal.classList.contains('card-modal') && modal.style.display !== 'none') {
setTimeout(function() {
enhanceActiveModal(modal);
}, 100);
}
}
});
});
document.querySelectorAll('.card-modal').forEach(function(modal) {
window.deckModalObserver.observe(modal, {
attributes: true,
attributeFilter: ['style']
});
});
}
// 增强当前活动的模态框
function enhanceActiveModal(modal) {
var cardId = modal.id ? modal.id.replace('-modal', ) : null;
if (!cardId) return;
var deckCard = null;
var uniqueId = null;
var unitIndex = null;
document.querySelectorAll('.deck-area .deck-card-wrapper').forEach(function(wrapper) {
var wrapperCard = wrapper.querySelector('.card-small-wrapper');
if (wrapperCard && wrapperCard.getAttribute('data-card-id') === cardId) {
deckCard = wrapper;
uniqueId = wrapper.getAttribute('data-unique-id');
unitIndex = wrapper.getAttribute('data-unit-index');
}
});
if (!deckCard || !uniqueId || !unitIndex) {
return;
}
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) {
return;
}
if (modal.hasAttribute('data-deck-enhanced')) {
return;
}
modal.setAttribute('data-deck-enhanced', 'true');
var inspirationButton = modal.querySelector('.inspiration-button');
if (inspirationButton) {
inspirationButton.addEventListener('click', function() {
setTimeout(function() {
enhanceInspirationView(modal, uniqueId, unitIndex);
}, 100);
});
}
var godButton = modal.querySelector('.god-inspiration-button');
if (godButton) {
godButton.addEventListener('click', function() {
setTimeout(function() {
enhanceGodView(modal, uniqueId, unitIndex);
}, 100);
});
}
}
// 关闭模态框并恢复滚动
function closeModalAndRestoreScroll(modal) {
modal.style.display = 'none';
modal.removeAttribute('data-deck-enhanced');
document.body.style.overflow = ;
document.body.style.position = ;
document.documentElement.style.overflow = ;
document.body.classList.remove('modal-open');
document.documentElement.classList.remove('modal-open');
window.dispatchEvent(new Event('resize'));
}
// 增强灵光一闪视图
function enhanceInspirationView(modal, uniqueId, unitIndex) {
var inspirationView = modal.querySelector('.inspiration-view');
if (!inspirationView) return;
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) return;
var variants = inspirationView.querySelectorAll('.inspiration-variant');
variants.forEach(function(variant, index) {
if (!variant.querySelector('.select-variant-btn')) {
var selectBtn = document.createElement('div');
selectBtn.className = 'select-variant-btn';
selectBtn.innerHTML = '选择此变体';
selectBtn.style.cssText = 'margin-top:10px;padding:8px 15px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;font-size:14px;font-weight:bold;border-radius:6px;cursor:pointer;text-align:center;';
selectBtn.addEventListener('click', function() {
replaceCard(uniqueId, unitIndex, '灵光一闪', index + 1);
closeModalAndRestoreScroll(modal);
});
variant.appendChild(selectBtn);
}
});
}
// 增强神光一闪视图
function enhanceGodView(modal, uniqueId, unitIndex) {
var godView = modal.querySelector('.god-inspiration-view');
if (!godView) return;
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) return;
var godGroups = godView.querySelectorAll('.god-group');
godGroups.forEach(function(group) {
var groupNameEl = group.querySelector('div[style*="color:#ffd36a"]');
if (!groupNameEl) return;
var groupName = groupNameEl.textContent.trim();
var variants = group.querySelectorAll('.god-variant-card');
variants.forEach(function(variant, index) {
if (!variant.querySelector('.select-variant-btn')) {
var selectBtn = document.createElement('div');
selectBtn.className = 'select-variant-btn';
selectBtn.innerHTML = '选择';
selectBtn.style.cssText = 'margin-top:5px;padding:6px 12px;background:linear-gradient(135deg,#28a745 0%,#218838 100%);color:white;font-size:12px;font-weight:bold;border-radius:4px;cursor:pointer;text-align:center;';
selectBtn.addEventListener('click', function() {
replaceCard(uniqueId, unitIndex, '神光一闪', groupName, index + 1);
closeModalAndRestoreScroll(modal);
});
variant.appendChild(selectBtn);
}
});
});
}
// 替换卡牌
function replaceCard(uniqueId, unitIndex, variantType, param1, param2) {
var cardData = characterUnits[unitIndex].selectedCards[uniqueId];
if (!cardData) {
console.error('找不到卡牌数据:', uniqueId);
return;
}
var wrapper = document.querySelector('[data-unique-id="' + uniqueId + '"]');
if (!wrapper) {
console.error('找不到卡牌容器:', uniqueId);
return;
}
cardData.variantType = variantType;
cardData.variantParam = param1;
cardData.variantIndex = param2;
var oldContent = wrapper.innerHTML;
wrapper.innerHTML = '
';
var invokeText = '错误: 找不到模块 "Module:卡牌/' + cardData.module + '"';
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: invokeText,
contentmodel: 'wikitext',
disablelimitreport: true
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
wrapper.innerHTML = data.parse.text['*'];
setTimeout(function() {
var newCard = wrapper.querySelector('.card-small-wrapper');
if (newCard) {
// 确保wrapper样式
wrapper.style.flexShrink = '0';
wrapper.style.display = 'inline-block';
var deleteBtn = document.createElement('div');
deleteBtn.className = 'card-delete-btn';
deleteBtn.innerHTML = '×';
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;';
deleteBtn.addEventListener('click', function(e) {
e.stopPropagation();
wrapper.remove();
delete characterUnits[unitIndex].selectedCards[uniqueId];
checkAndShowPlaceholder(unitIndex);
});
newCard.style.position = 'relative';
newCard.appendChild(deleteBtn);
}
setupGlobalModalListener();
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
}, 100);
} else {
wrapper.innerHTML = oldContent;
}
})
.catch(error => {
console.error('替换卡牌失败:', error);
wrapper.innerHTML = oldContent;
document.body.style.overflow = ;
document.documentElement.style.overflow = ;
});
}
// 选择角色
document.getElementById('character-list').addEventListener('click', function(e) {
var characterOption = e.target.closest('.character-option');
if (characterOption && currentActiveUnit) {
var characterName = characterOption.getAttribute('data-character-name') ||
characterOption.getAttribute('data-name') ||
characterOption.getAttribute('title');
var characterClass = characterOption.getAttribute('data-class') ||
characterOption.getAttribute('data-职业');
if (!characterName) {
var nameEl = characterOption.querySelector('.character-name, [class*="name"]');
if (nameEl) characterName = nameEl.textContent.trim();
}
characterUnits[currentActiveUnit].characterClass = characterClass;
var clonedCard = characterOption.cloneNode(true);
clonedCard.classList.remove('character-option');
clonedCard.style.cursor = 'default';
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]');
var characterSlot = unit.querySelector('.character-slot');
characterSlot.innerHTML = ;
characterSlot.appendChild(clonedCard);
characterSlot.style.border = 'none';
document.getElementById('character-modal').style.display = 'none';
if (characterName) {
loadCharacterCards(characterName, currentActiveUnit);
}
}
});
// 选择伙伴
document.querySelectorAll('.partner-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
document.getElementById('partner-modal').style.display = 'block';
});
});
document.getElementById('close-partner-modal').addEventListener('click', function() {
document.getElementById('partner-modal').style.display = 'none';
});
document.getElementById('partner-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
document.getElementById('partner-list').addEventListener('click', function(e) {
var partnerOption = e.target.closest('.partner-option');
if (partnerOption && currentActiveUnit) {
var partnerId = partnerOption.dataset.partnerId || partnerOption.getAttribute('data-partner-id');
var partnerImg = document.createElement('img');
partnerImg.src = '/index.php?title=Special:Redirect/file/Portrait_character_wide_' + partnerId + '.png';
partnerImg.style.width = '159px';
partnerImg.style.height = '77px';
partnerImg.style.objectFit = 'cover';
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]');
var partnerSlot = unit.querySelector('.partner-slot');
partnerSlot.innerHTML = ;
partnerSlot.appendChild(partnerImg);
partnerSlot.style.border = 'none';
document.getElementById('partner-modal').style.display = 'none';
}
});
// ========== 卡牌添加功能 ==========
var currentDeckArea = null;
var currentCardType = 'character';
// 点击卡组区域打开卡牌选择
document.querySelectorAll('.deck-area').forEach(function(deckArea) {
var originalClickHandler = function(e) {
if (e.target.closest('.deck-card-wrapper') ||
e.target.closest('.card-small-wrapper') ||
e.target.closest('.card-delete-btn') ||
e.target.classList.contains('card-delete-btn')) {
return;
}
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
currentDeckArea = this;
var unit = this.closest('.character-unit');
var characterSlot = unit.querySelector('.character-slot');
var hasCharacter = characterSlot.querySelector('img') !== null ||
characterSlot.innerHTML.indexOf('data-character-name') > -1 ||
!characterSlot.querySelector('.placeholder');
var unitData = characterUnits[currentActiveUnit];
if (!unitData.characterName) {
hasCharacter = false;
}
if (!hasCharacter) {
alert('请先选择战斗员!');
return;
}
currentCardType = 'character';
document.querySelectorAll('.card-type-tab').forEach(function(tab) {
tab.classList.remove('active');
tab.style.borderBottomColor = 'transparent';
tab.style.fontWeight = 'normal';
});
var characterTab = document.querySelector('.card-type-tab[data-type="character"]');
if (characterTab) {
characterTab.classList.add('active');
characterTab.style.borderBottomColor = '#667eea';
characterTab.style.fontWeight = 'bold';
}
document.getElementById('card-modal').style.display = 'block';
loadCardList('character');
};
deckArea.addEventListener('click', originalClickHandler);
});
// 卡牌类型标签切换
document.querySelectorAll('.card-type-tab').forEach(function(tab) {
tab.addEventListener('click', function() {
var cardType = this.getAttribute('data-type');
currentCardType = cardType;
document.querySelectorAll('.card-type-tab').forEach(function(t) {
t.classList.remove('active');
t.style.borderBottomColor = 'transparent';
t.style.fontWeight = 'normal';
});
this.classList.add('active');
this.style.borderBottomColor = '#667eea';
this.style.fontWeight = 'bold';
loadCardList(cardType);
});
});
// 加载卡牌列表
function loadCardList(cardType) {
var listContainer = document.getElementById('card-selection-list');
listContainer.innerHTML = '
';
var apiUrl = mw.util.wikiScript('api');
var invokeText = ;
if (cardType === 'character') {
var unitData = characterUnits[currentActiveUnit];
if (!unitData.characterName) {
listContainer.innerHTML = '
';
return;
}
invokeText = '错误: 找不到模块 "Module:卡牌/' + unitData.characterName + '"';
} else if (cardType === 'neutral') {
var unitData = characterUnits[currentActiveUnit];
var characterClass = unitData.characterClass;
if (characterClass) {
invokeText = '错误: 没有找到职业为 "' + characterClass + '" 的中立卡牌';
} else {
invokeText = '
';
}
} else if (cardType === 'monster') {
invokeText = '
';
}
var params = {
action: 'parse',
format: 'json',
text: invokeText,
contentmodel: 'wikitext',
disablelimitreport: true,
wrapoutputclass:
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
listContainer.innerHTML = data.parse.text['*'];
setTimeout(function() {
addCardSelectionHandlers(cardType);
}, 100);
} else {
listContainer.innerHTML = '
';
}
})
.catch(error => {
console.error('加载卡牌失败:', error);
listContainer.innerHTML = '
';
});
}
// 添加卡牌选择处理器
function addCardSelectionHandlers(cardType) {
var listContainer = document.getElementById('card-selection-list');
if (cardType === 'character') {
var wrappers = listContainer.querySelectorAll('.deck-card-wrapper');
wrappers.forEach(function(wrapper) {
wrapper.style.cursor = 'pointer';
wrapper.style.transition = 'transform 0.2s';
wrapper.addEventListener('mouseenter', function() {
this.style.transform = 'scale(1.05)';
});
wrapper.addEventListener('mouseleave', function() {
this.style.transform = 'scale(1)';
});
wrapper.addEventListener('click', function(e) {
e.stopPropagation();
var cardName = this.getAttribute('data-card');
var card = this.querySelector('.card-small-wrapper');
if (!cardName && card) {
cardName = card.getAttribute('data-card');
}
if (!cardName) {
console.error('无法获取卡牌名称');
return;
}
var hasInspiration = card && card.querySelector('.inspiration-button');
var hasGodInspiration = card && card.querySelector('.god-inspiration-button');
if (hasInspiration || hasGodInspiration) {
showVariantSelectionDialog(cardName, 'character');
} else {
addCardToDeckByName(cardName, 'character');
}
});
});
} else {
var cards = listContainer.querySelectorAll('.card-small-wrapper');
cards.forEach(function(card) {
card.style.cursor = 'pointer';
card.style.transition = 'transform 0.2s';
card.addEventListener('mouseenter', function() {
this.style.transform = 'scale(1.05)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'scale(1)';
});
card.addEventListener('click', function(e) {
e.stopPropagation();
addCardToDeck(this, cardType);
});
});
}
}
// 显示变体选择对话框
function showVariantSelectionDialog(cardName, cardType) {
var dialog = document.createElement('div');
dialog.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:30px;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,0.3);z-index:10001;min-width:300px;';
var html = '
选择添加方式
'; html += '
卡牌: ' + cardName + '
'; html += '
';
dialog.innerHTML = html;
var overlay = document.createElement('div');
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:10000;';
document.body.appendChild(overlay);
document.body.appendChild(dialog);
dialog.querySelectorAll('.variant-option-btn').forEach(function(btn) {
btn.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px)';
this.style.boxShadow = '0 5px 15px rgba(0,0,0,0.2)';
});
btn.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
this.style.boxShadow = 'none';
});
});
dialog.addEventListener('click', function(e) {
var btn = e.target.closest('.variant-option-btn');
if (!btn) return;
var action = btn.getAttribute('data-action');
if (action === 'base') {
addCardToDeckByName(cardName, cardType);
document.body.removeChild(overlay);
document.body.removeChild(dialog);
document.getElementById('card-modal').style.display = 'none';
} else if (action === 'view') {
addCardToDeckByName(cardName, cardType, function() {
document.body.removeChild(overlay);
document.body.removeChild(dialog);
document.getElementById('card-modal').style.display = 'none';
setTimeout(function() {
alert('卡牌已添加!现在您可以点击卡牌查看并选择变体。');
}, 300);
});
} else {
document.body.removeChild(overlay);
document.body.removeChild(dialog);
}
});
}
// 按名称添加卡牌到卡组
function addCardToDeckByName(cardName, cardType, callback) {
if (!currentDeckArea || !currentActiveUnit) return;
var unitData = characterUnits[currentActiveUnit];
var moduleName = ;
if (cardType === 'character') {
moduleName = unitData.characterName;
} else if (cardType === 'neutral') {
moduleName = '中立';
} else if (cardType === 'monster') {
moduleName = '怪物';
}
var invokeText = ;
if (cardType === 'character') {
invokeText = '错误: 找不到模块 "Module:卡牌/' + moduleName + '"';
} else if (cardType === 'neutral') {
invokeText = '错误: 找不到中立卡牌 "' + cardName + '"';
} else if (cardType === 'monster') {
invokeText = '错误: 找不到怪物 "' + cardName + '"';
}
var apiUrl = mw.util.wikiScript('api');
var params = {
action: 'parse',
format: 'json',
text: invokeText,
contentmodel: 'wikitext',
disablelimitreport: true
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
// 移除占位符
var placeholder = currentDeckArea.querySelector('.deck-placeholder');
if (placeholder) {
placeholder.remove();
}
var wrapper = document.createElement('div');
wrapper.className = 'deck-card-wrapper';
wrapper.innerHTML = data.parse.text['*'];
wrapper.setAttribute('data-module', moduleName);
wrapper.setAttribute('data-card', cardName);
// 确保wrapper不会换行
wrapper.style.flexShrink = '0';
wrapper.style.display = 'inline-block';
var uniqueId = 'deck-card-' + currentActiveUnit + '-' + (++unitData.cardIdCounter);
wrapper.setAttribute('data-unique-id', uniqueId);
wrapper.setAttribute('data-unit-index', currentActiveUnit);
unitData.selectedCards[uniqueId] = {
module: moduleName,
cardName: cardName,
variantType: null,
variantParam: null,
variantIndex: null
};
currentDeckArea.appendChild(wrapper);
setTimeout(function() {
var card = wrapper.querySelector('.card-small-wrapper');
if (card) {
var deleteBtn = document.createElement('div');
deleteBtn.className = 'card-delete-btn';
deleteBtn.innerHTML = '×';
deleteBtn.style.cssText = 'position:absolute;top:5px;right:5px;width:20px;height:20px;background:rgba(255,0,0,0.7);color:white;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:100;font-size:16px;line-height:1;font-weight:bold;';
deleteBtn.addEventListener('click', function(e) {
e.stopPropagation();
wrapper.remove();
delete unitData.selectedCards[uniqueId];
checkAndShowPlaceholder(currentActiveUnit);
});
card.style.position = 'relative';
card.appendChild(deleteBtn);
}
setupGlobalModalListener();
if (callback) callback();
}, 100);
} else {
alert('添加卡牌失败');
}
})
.catch(error => {
console.error('添加卡牌失败:', error);
alert('添加卡牌出错:' + error.message);
});
}
// 添加卡牌到卡组(从元素获取信息)
function addCardToDeck(cardElement, cardType) {
if (!currentDeckArea || !currentActiveUnit) return;
var cardName = cardElement.getAttribute('data-card-name') ||
cardElement.getAttribute('data-card');
if (!cardName) {
var parent = cardElement.closest('[data-card]');
if (parent) {
cardName = parent.getAttribute('data-card');
}
}
if (!cardName) {
var parent = cardElement.closest('[data-card-name]');
if (parent) {
cardName = parent.getAttribute('data-card-name');
}
}
if (!cardName) {
var wrapper = cardElement.closest('.deck-card-wrapper');
if (wrapper) {
cardName = wrapper.getAttribute('data-card');
}
}
if (!cardName) {
console.error('无法获取卡牌名称');
alert('错误:无法获取卡牌名称');
return;
}
addCardToDeckByName(cardName, cardType, function() {
document.getElementById('card-modal').style.display = 'none';
});
}
// 关闭卡牌选择窗口
document.getElementById('close-card-modal').addEventListener('click', function() {
document.getElementById('card-modal').style.display = 'none';
});
document.getElementById('card-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
// ========== 装备选择功能 ==========
document.querySelectorAll('.equipment-slot').forEach(function(slot) {
slot.addEventListener('click', function() {
currentActiveUnit = this.closest('.character-unit').getAttribute('data-unit-index');
var equipmentType = this.getAttribute('data-equipment-type');
var titleMap = {
'weapon': '选择武器',
'armor': '选择装甲',
'ring': '选择戒指'
};
document.getElementById('equipment-modal-title').textContent = titleMap[equipmentType] || '选择装备';
loadEquipmentList(equipmentType);
document.getElementById('equipment-modal').style.display = 'block';
});
});
document.getElementById('close-equipment-modal').addEventListener('click', function() {
document.getElementById('equipment-modal').style.display = 'none';
});
document.getElementById('equipment-modal').addEventListener('click', function(e) {
if (e.target === this) {
this.style.display = 'none';
}
});
function loadEquipmentList(equipmentType) {
var listContainer = document.getElementById('equipment-list');
listContainer.innerHTML = '
';
var categoryMap = {
'weapon': '武器',
'armor': '装甲',
'ring': '戒指'
};
var category = categoryMap[equipmentType];
var apiUrl = mw.util.wikiScript('api');
var askQuery = ;
var params = {
action: 'parse',
format: 'json',
text: askQuery,
contentmodel: 'wikitext',
disablelimitreport: true
};
fetch(apiUrl + '?' + new URLSearchParams(params))
.then(response => response.json())
.then(data => {
if (data.parse && data.parse.text) {
listContainer.innerHTML = data.parse.text['*'];
setTimeout(function() {
addEquipmentSelectionHandlers(equipmentType);
}, 100);
} else {
listContainer.innerHTML = '
';
}
})
.catch(error => {
console.error('加载装备失败:', error);
listContainer.innerHTML = '
';
});
}
function addEquipmentSelectionHandlers(equipmentType) {
var equipmentOptions = document.querySelectorAll('#equipment-list .equipment-option');
equipmentOptions.forEach(function(option) {
option.style.cursor = 'pointer';
option.style.transition = 'all 0.3s';
option.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-5px)';
this.style.boxShadow = '0 5px 20px rgba(102,126,234,0.4)';
});
option.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
this.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
});
option.addEventListener('click', function() {
var equipmentId = this.getAttribute('data-equipment-id');
var equipmentImg = this.querySelector('img');
if (equipmentImg && currentActiveUnit) {
var unit = document.querySelector('.character-unit[data-unit-index="' + currentActiveUnit + '"]');
var slot = unit.querySelector('.equipment-slot[data-equipment-type="' + equipmentType + '"]');
var clonedImg = equipmentImg.cloneNode(true);
clonedImg.style.width = '100px';
clonedImg.style.height = '100px';
clonedImg.style.objectFit = 'contain';
slot.innerHTML = ;
slot.appendChild(clonedImg);
slot.style.border = 'none';
document.getElementById('equipment-modal').style.display = 'none';
}
});
});
}
// 初始化:设置默认角色1为激活单元
currentActiveUnit = '0';
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTeamSimulator);
} else {
initTeamSimulator();
}
})(); </script>
<style>
- team-simulator {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
- save-team-btn:hover {
transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0,0,0,0.15);
}
- save-team-btn:active {
transform: translateY(0);
}
.character-unit {
background: white; transition: all 0.3s;
}
.character-slot, .partner-slot {
transition: all 0.3s; overflow: hidden;
}
.character-slot:hover, .partner-slot:hover {
border-color: #667eea; background: #f9f9ff;
}
.deck-area {
transition: border-color 0.3s, background 0.3s;
}
.deck-area:hover {
border-color: #667eea;
}
/* 确保卡牌wrapper不换行 */ .deck-card-wrapper {
flex-shrink: 0; display: inline-block;
}
/* 确保中立和怪物卡牌也不换行 */
- card-selection-list .deck-card-wrapper,
- card-selection-list .card-small-wrapper {
flex-shrink: 0; display: inline-block;
}
.equipment-slot {
transition: all 0.3s;
}
.equipment-slot:hover {
border-color: #667eea; background: #f9f9ff;
}
/* 模态框样式优化 */
- card-modal, #character-modal, #partner-modal, #equipment-modal {
animation: fadeIn 0.3s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 模态框内容动画 */
- card-modal > div,
- character-modal > div,
- partner-modal > div,
- equipment-modal > div {
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
transform: translate(-50%, -60%);
opacity: 0;
}
to {
transform: translate(-50%, -50%);
opacity: 1;
}
}
/* 卡牌类型标签样式 */ .card-type-tab {
transition: all 0.3s;
}
.card-type-tab:hover {
color: #667eea; background: rgba(102, 126, 234, 0.05);
}
.card-type-tab.active {
color: #667eea;
}
/* 角色和伙伴选项样式 */ .character-option, .partner-option {
transition: all 0.3s;
}
.character-option:hover, .partner-option:hover {
transform: translateY(-5px); box-shadow: 0 5px 20px rgba(102,126,234,0.4);
}
/* 装备选项样式 */ .equipment-option {
cursor: pointer; padding: 10px; border: 2px solid transparent; border-radius: 8px; transition: all 0.3s; background: white;
}
.equipment-option:hover {
border-color: #667eea; transform: translateY(-5px); box-shadow: 0 5px 20px rgba(102,126,234,0.4);
}
/* 删除按钮样式优化 */ .card-delete-btn {
transition: all 0.2s; user-select: none;
}
.card-delete-btn:hover {
background: rgba(255,0,0,0.9); transform: scale(1.2);
}
/* 占位符样式 */ .deck-placeholder {
pointer-events: none; user-select: none;
}
/* 变体选择按钮样式 */ .select-variant-btn {
transition: all 0.3s; user-select: none;
}
.select-variant-btn:hover {
transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.select-variant-btn:active {
transform: translateY(0);
}
/* 卡牌选择列表样式优化 */
- card-selection-list {
max-height: 60vh; overflow-y: auto;
}
/* 自定义滚动条 */
- card-selection-list::-webkit-scrollbar,
- character-list::-webkit-scrollbar,
- partner-list::-webkit-scrollbar,
- equipment-list::-webkit-scrollbar {
width: 8px;
}
- card-selection-list::-webkit-scrollbar-track,
- character-list::-webkit-scrollbar-track,
- partner-list::-webkit-scrollbar-track,
- equipment-list::-webkit-scrollbar-track {
background: #f1f1f1; border-radius: 4px;
}
- card-selection-list::-webkit-scrollbar-thumb,
- character-list::-webkit-scrollbar-thumb,
- partner-list::-webkit-scrollbar-thumb,
- equipment-list::-webkit-scrollbar-thumb {
background: #888; border-radius: 4px;
}
- card-selection-list::-webkit-scrollbar-thumb:hover,
- character-list::-webkit-scrollbar-thumb:hover,
- partner-list::-webkit-scrollbar-thumb:hover,
- equipment-list::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* 响应式设计 */ @media (max-width: 1200px) {
#team-content {
max-width: 100%;
padding: 10px;
}
.character-unit {
padding: 15px;
}
}
@media (max-width: 768px) {
.character-unit > div {
flex-direction: column;
}
.character-unit > div > div {
width: 100% !important;
}
.deck-area {
min-height: 200px;
}
#card-modal > div,
#character-modal > div,
#partner-modal > div,
#equipment-modal > div {
width: 95%;
max-width: 95%;
min-width: auto;
padding: 15px;
}
.card-type-tab {
padding: 8px 12px;
font-size: 14px;
}
#save-team-btn {
padding: 10px 20px;
font-size: 14px;
}
}
/* 卡牌hover效果 */ .deck-card-wrapper:hover {
z-index: 10;
}
.card-small-wrapper {
transition: transform 0.2s;
}
.deck-card-wrapper:hover .card-small-wrapper {
transform: scale(1.05);
}
/* 加载动画 */ @keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 关闭按钮样式 */
- close-card-modal,
- close-character-modal,
- close-partner-modal,
- close-equipment-modal {
transition: all 0.3s; user-select: none;
}
- close-card-modal:hover,
- close-character-modal:hover,
- close-partner-modal:hover,
- close-equipment-modal:hover {
color: #ff6b6b; transform: rotate(90deg) scale(1.2);
}
/* 变体对话框按钮动画 */ .variant-option-btn {
position: relative; overflow: hidden;
}
.variant-option-btn::before {
content: ; position: absolute; top: 50%; left: 50%; width: 0; height: 0; border-radius: 50%; background: rgba(255,255,255,0.3); transform: translate(-50%, -50%); transition: width 0.6s, height 0.6s;
}
.variant-option-btn:hover::before {
width: 300px; height: 300px;
}
/* 确保弹窗内容居中 */
- card-modal > div,
- character-modal > div,
- partner-modal > div,
- equipment-modal > div {
box-sizing: border-box;
}
/* 网格布局优化 */
- character-list,
- partner-list {
display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 15px; justify-items: center;
}
- equipment-list {
display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 15px; justify-items: center;
}
/* 图片加载优化 */ img {
image-rendering: -webkit-optimize-contrast;
}
/* 防止文本选择 */ .character-slot, .partner-slot, .deck-area, .equipment-slot, .card-type-tab,
- save-team-btn {
user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;
}
/* 工具提示样式(如果需要) */ [data-tooltip] {
position: relative;
}
[data-tooltip]::after {
content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); padding: 5px 10px; background: rgba(0,0,0,0.8); color: white; border-radius: 4px; font-size: 12px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity 0.3s;
}
[data-tooltip]:hover::after {
opacity: 1;
}
/* 确保deck-area内的flex布局正确 */ .deck-area {
box-sizing: border-box;
}
.deck-area > * {
box-sizing: border-box;
}
/* 修复可能的布局问题 */ .character-unit > div {
box-sizing: border-box;
}
.character-unit > div > div {
box-sizing: border-box;
}
/* 打印样式优化 */ @media print {
#save-team-btn,
.card-delete-btn,
#card-modal,
#character-modal,
#partner-modal,
#equipment-modal {
display: none !important;
}
.character-unit {
page-break-inside: avoid;
}
}
/* 无障碍支持 */ button, [role="button"], .character-option, .partner-option, .equipment-option, .card-type-tab {
outline-offset: 2px;
}
button:focus, [role="button"]:focus, .character-option:focus, .partner-option:focus, .equipment-option:focus, .card-type-tab:focus {
outline: 2px solid #667eea;
}
/* 暗色模式支持(如果需要) */ @media (prefers-color-scheme: dark) {
/* 可以在这里添加暗色模式样式 */
} </style>









































