Fix Grabej
This commit is contained in:
101
public/game.js
101
public/game.js
@ -1187,6 +1187,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Если это Грабеж, но spellTarget не enemy_player, все равно активируем режим выбора цели
|
||||
if (meta.spellEffect === 'steal_cards' && !meta.spellTarget) {
|
||||
spellMode = { active: true, handIndex: handIndex, cardId: wrap.dataset.cardId, spellTarget: 'enemy_player' };
|
||||
$('spell-mode')?.classList.remove('hidden');
|
||||
renderGame(state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!needTarget) {
|
||||
if (typeof window.Sounds !== 'undefined') window.Sounds.playCard();
|
||||
socket.emit('playSpell', { handIndex: handIndex });
|
||||
@ -2238,14 +2246,25 @@
|
||||
const hintEl = $('steal-cards-hint');
|
||||
const targetSelect = $('steal-target-select');
|
||||
|
||||
if (!deckList || !selectedEl || !confirmBtn) return;
|
||||
if (!deckList || !selectedEl || !confirmBtn) {
|
||||
console.error('Steal cards modal elements not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const currentState = gameState || state;
|
||||
if (!currentState || !currentState.players) {
|
||||
console.error('Invalid game state for steal cards modal');
|
||||
return;
|
||||
}
|
||||
|
||||
// Если противник уже выбран, показываем его колоду
|
||||
if (stealCardsMode.targetPlayerIndex !== null) {
|
||||
// Обновляем колоду из актуального gameState
|
||||
const targetPlayer = state.players[stealCardsMode.targetPlayerIndex];
|
||||
const targetPlayer = currentState.players[stealCardsMode.targetPlayerIndex];
|
||||
if (targetPlayer && targetPlayer.deck) {
|
||||
stealCardsMode.targetDeck = [...targetPlayer.deck];
|
||||
} else {
|
||||
console.warn('Target player not found or deck is empty:', stealCardsMode.targetPlayerIndex);
|
||||
}
|
||||
|
||||
if (stealCardsMode.targetDeck.length === 0) {
|
||||
@ -2263,39 +2282,65 @@
|
||||
}
|
||||
|
||||
deckList.innerHTML = stealCardsMode.targetDeck.map((cardId, idx) => {
|
||||
const meta = cardDb[cardId];
|
||||
if (!meta) return '';
|
||||
const cardDbToUse = currentState?.cardDb || cardDb;
|
||||
const meta = cardDbToUse[cardId];
|
||||
if (!meta) {
|
||||
console.warn('Card not found in cardDb:', cardId, 'Available keys:', Object.keys(cardDbToUse).slice(0, 10));
|
||||
return `<div class="card-wrap steal-deck-card" data-card-id="${cardId}" data-deck-index="${idx}" style="width: 100px; height: 140px; cursor: pointer; border: 2px solid red; position: relative; z-index: 10;">
|
||||
<div style="padding: 0.5rem; text-align: center; font-size: 0.7rem; color: #ff6b6b;">Карта ${cardId}</div>
|
||||
</div>`;
|
||||
}
|
||||
const isSelected = stealCardsMode.selectedIndices.includes(idx);
|
||||
const cost = meta.cost || 0;
|
||||
const attack = meta.attack !== undefined ? meta.attack : '';
|
||||
const health = meta.health !== undefined ? meta.health : '';
|
||||
const stats = meta.type === 'minion' ? `<div class="card-stats"><span class="atk">${attack}</span><span class="hp">${health}</span></div>` : '';
|
||||
const costDisplay = `<div class="card-cost-wrap"><span class="card-cost">${cost}</span></div>`;
|
||||
const art = getCardArt ? getCardArt(meta) : '✦';
|
||||
const art = typeof getCardArt === 'function' ? getCardArt(meta) : '✦';
|
||||
|
||||
return `<div class="card-wrap steal-deck-card ${isSelected ? 'selected' : ''}" data-card-id="${cardId}" data-deck-index="${idx}" style="width: 100px; height: 140px; cursor: pointer;">
|
||||
return `<div class="card-wrap steal-deck-card ${isSelected ? 'selected' : ''}" data-card-id="${cardId}" data-deck-index="${idx}" style="width: 100px; height: 140px; cursor: pointer; position: relative; z-index: 10;">
|
||||
<div class="card faction-${meta.faction || 'neutral'}">
|
||||
<div class="card-art">${art}</div>
|
||||
<div class="card-info">
|
||||
<div class="card-name" style="font-size: 0.7rem;">${escapeHtml(meta.name)}</div>
|
||||
<div class="card-name" style="font-size: 0.7rem;">${escapeHtml(meta.name || cardId)}</div>
|
||||
${stats}
|
||||
${costDisplay}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}).filter(Boolean).join('');
|
||||
}).join('');
|
||||
|
||||
$all('.steal-deck-card').forEach(card => {
|
||||
card.onclick = function() {
|
||||
const handleCardClick = function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const idx = parseInt(card.dataset.deckIndex, 10);
|
||||
if (isNaN(idx)) {
|
||||
console.warn('Invalid deck index:', card.dataset.deckIndex);
|
||||
return;
|
||||
}
|
||||
const selectedIdx = stealCardsMode.selectedIndices.indexOf(idx);
|
||||
if (selectedIdx >= 0) {
|
||||
stealCardsMode.selectedIndices.splice(selectedIdx, 1);
|
||||
} else if (stealCardsMode.selectedIndices.length < 2) {
|
||||
stealCardsMode.selectedIndices.push(idx);
|
||||
}
|
||||
showStealCardsModal(state, data);
|
||||
const currentState = gameState || state;
|
||||
showStealCardsModal(currentState, data || {
|
||||
targetPlayerIndex: stealCardsMode.targetPlayerIndex,
|
||||
targetPlayerName: currentState?.players?.[stealCardsMode.targetPlayerIndex]?.name || `Игрок ${stealCardsMode.targetPlayerIndex + 1}`,
|
||||
targetDeckSize: stealCardsMode.targetDeck.length,
|
||||
maxCards: Math.min(2, stealCardsMode.targetDeck.length)
|
||||
});
|
||||
};
|
||||
card.onclick = handleCardClick;
|
||||
card.style.pointerEvents = 'auto';
|
||||
if (isTouchDevice()) {
|
||||
card.ontouchstart = function(e) {
|
||||
e.preventDefault();
|
||||
handleCardClick(e);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
selectedEl.innerHTML = stealCardsMode.selectedIndices.length ? stealCardsMode.selectedIndices.map(idx => {
|
||||
@ -2330,9 +2375,14 @@
|
||||
hintEl.textContent = 'Выберите противника для грабежа';
|
||||
}
|
||||
|
||||
const enemies = state.players.filter((p, i) => i !== state.yourIndex && p.health > 0 && p.deck && p.deck.length > 0);
|
||||
const enemies = currentState.players.filter((p, i) => i !== currentState.yourIndex && p.health > 0 && p.deck && p.deck.length > 0);
|
||||
if (enemies.length === 0) {
|
||||
if (hintEl) hintEl.textContent = 'Нет доступных противников для грабежа';
|
||||
targetSelect.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
targetSelect.innerHTML = enemies.map((enemy, idx) => {
|
||||
const enemyIdx = state.players.indexOf(enemy);
|
||||
const enemyIdx = currentState.players.indexOf(enemy);
|
||||
return `<div class="steal-target-option" data-player-index="${enemyIdx}" style="padding: 1rem; margin: 0.5rem 0; background: rgba(0,0,0,0.3); border: 2px solid rgba(0,180,255,0.3); border-radius: 8px; cursor: pointer; transition: all 0.2s;">
|
||||
<div style="font-weight: 700; color: var(--cyan);">${escapeHtml(enemy.name || `Игрок ${enemyIdx + 1}`)}</div>
|
||||
<div style="font-size: 0.85rem; color: #94a3b8; margin-top: 0.25rem;">Колода: ${enemy.deck.length} карт</div>
|
||||
@ -2340,21 +2390,40 @@
|
||||
}).join('');
|
||||
|
||||
$all('.steal-target-option').forEach(option => {
|
||||
option.onclick = function() {
|
||||
const handleOptionClick = function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const playerIdx = parseInt(option.dataset.playerIndex, 10);
|
||||
const targetPlayer = state.players[playerIdx];
|
||||
if (isNaN(playerIdx)) return;
|
||||
const currentState = gameState || state;
|
||||
if (!currentState || !currentState.players) {
|
||||
console.error('Invalid state when selecting target player');
|
||||
return;
|
||||
}
|
||||
const targetPlayer = currentState.players[playerIdx];
|
||||
if (targetPlayer && targetPlayer.deck && targetPlayer.deck.length > 0) {
|
||||
stealCardsMode.targetPlayerIndex = playerIdx;
|
||||
// Получаем актуальную колоду из gameState
|
||||
stealCardsMode.targetDeck = targetPlayer.deck ? [...targetPlayer.deck] : [];
|
||||
showStealCardsModal(state, {
|
||||
console.log('Selected target player:', playerIdx, 'Deck size:', stealCardsMode.targetDeck.length);
|
||||
showStealCardsModal(currentState, {
|
||||
targetPlayerIndex: playerIdx,
|
||||
targetPlayerName: targetPlayer.name || `Игрок ${playerIdx + 1}`,
|
||||
targetDeckSize: targetPlayer.deck.length,
|
||||
maxCards: Math.min(2, targetPlayer.deck.length)
|
||||
});
|
||||
} else {
|
||||
console.warn('Target player has no deck or is invalid:', playerIdx, targetPlayer);
|
||||
}
|
||||
};
|
||||
option.onclick = handleOptionClick;
|
||||
option.style.pointerEvents = 'auto';
|
||||
option.style.cursor = 'pointer';
|
||||
if (isTouchDevice()) {
|
||||
option.ontouchstart = function(e) {
|
||||
e.preventDefault();
|
||||
handleOptionClick(e);
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1937,11 +1937,20 @@ html, body {
|
||||
.steal-target-select {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.steal-target-option {
|
||||
pointer-events: auto !important;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.steal-target-option:hover {
|
||||
background: rgba(0,180,255,0.2) !important;
|
||||
border-color: var(--cyan) !important;
|
||||
transform: scale(1.02);
|
||||
}
|
||||
.steal-target-option:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
.steal-deck-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
|
||||
@ -1957,14 +1966,24 @@ html, body {
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
border: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
pointer-events: auto !important;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.steal-deck-card:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 0 15px rgba(0,180,255,0.5);
|
||||
z-index: 15;
|
||||
}
|
||||
.steal-deck-card.selected {
|
||||
border-color: var(--cyan);
|
||||
box-shadow: 0 0 20px rgba(0,180,255,0.7);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
.steal-deck-card:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
.steal-selected {
|
||||
min-height: 80px;
|
||||
|
||||
Reference in New Issue
Block a user