diff --git a/public/game.js b/public/game.js
index fbc5ee7..af5354b 100644
--- a/public/game.js
+++ b/public/game.js
@@ -282,11 +282,12 @@
yourIndex = -1;
const spectatorBadge = $('spectator-badge');
if (!spectatorBadge) {
- const badge = document.createElement('div');
- badge.id = 'spectator-badge';
- badge.style.cssText = 'position: fixed; top: 1rem; right: 1rem; background: rgba(212,168,75,0.9); color: #000; padding: 0.5rem 1rem; border-radius: 8px; font-weight: 700; z-index: 200;';
- badge.textContent = '👁 НАБЛЮДАТЕЛЬ';
- document.body.appendChild(badge);
+ const badge = document.createElement('div');
+ badge.id = 'spectator-badge';
+ badge.style.cssText = 'position: fixed; top: 1rem; right: 1rem; background: rgba(212,168,75,0.9); color: #000; padding: 0.5rem 1rem; border-radius: 8px; font-weight: 700; z-index: 200; display: flex; align-items: center; gap: 0.5rem;';
+ badge.innerHTML = 'НАБЛЮДАТЕЛЬ';
+ document.body.appendChild(badge);
+ if (typeof lucide !== 'undefined') lucide.createIcons();
}
} else {
const spectatorBadge = $('spectator-badge');
@@ -367,6 +368,11 @@
resetBtn.classList.toggle('hidden', state.yourIndex !== 0);
}
bindGameEvents(state);
+
+ // Обновляем иконки Lucide после рендеринга
+ if (typeof lucide !== 'undefined') {
+ setTimeout(() => lucide.createIcons(), 100);
+ }
}
function showGameOver(state) {
@@ -435,18 +441,22 @@
const isCurrent = state.currentPlayerIndex === i;
const isDead = p.health <= 0 || p.isDead;
const name = p.name || 'Игрок ' + (i + 1);
+ const isAI = p.isAI || false;
const minions = (p.board || []).map((m, j) => renderBoardMinion(m, i, j, state, true, false));
const heroBar = renderHeroTarget(i, state);
const heroDrop = renderHeroDropZone(i, state);
const canSteal = !state.isSpectator && state.currentPlayerIndex === state.yourIndex && spellMode.active && spellMode.cardId && cardDb[spellMode.cardId]?.spellEffect === 'steal_cards';
return `
-
${escapeHtml(name)}${isDead ? ' ✝' : ''}
+
+ ${isAI ? '' : ''}
+ ${escapeHtml(name)}${isDead ? ' ' : ''}
+
- ❤ ${p.health ?? 30}
- ${(p.armor || 0) > 0 ? `🛡 ${p.armor}` : ''}
- 🔵 ${p.mana ?? 0}/${p.maxMana ?? 0}
- ${p.deck && p.deck.length > 0 ? `📚 ${p.deck.length}` : ''}
+ ${p.health ?? 30}
+ ${(p.armor || 0) > 0 ? `${p.armor}` : ''}
+ ${p.mana ?? 0}/${p.maxMana ?? 0}
+ ${p.deck && p.deck.length > 0 ? `${p.deck.length}` : ''}
${heroDrop}${heroBar}${minions.join('')}
`;
@@ -526,7 +536,7 @@
const attackerName = attackerCard?.name || 'Миньон';
const targetName = targetCard?.name || 'Миньон';
const damage = logEntry.damage || attackerMinion?.attack || 0;
- text = who(attackerIdx) + ' → ' + attackerName + ' ⚔ атакует ' + targetName + ' (' + damage + ' урона) → ' + who(targetIdx);
+ text = who(attackerIdx) + ' → ' + attackerName + ' атакует ' + targetName + ' (' + damage + ' урона) → ' + who(targetIdx);
}
} else if (logEntry.type === 'attackHero' && logEntry.fromPlayer !== undefined && logEntry.toPlayer !== undefined) {
const attackerPlayer = state.players[logEntry.fromPlayer];
@@ -537,10 +547,10 @@
const attackerCard = cardDb[attackerMinion?.cardId];
const attackerName = attackerCard?.name || 'Миньон';
const damage = logEntry.damage || attackerMinion?.attack || 0;
- text = who(logEntry.fromPlayer) + ' → ' + attackerName + ' ⚔ атакует героя ' + who(logEntry.toPlayer) + ' (' + damage + ' урона)!';
+ text = who(logEntry.fromPlayer) + ' → ' + attackerName + ' атакует героя ' + who(logEntry.toPlayer) + ' (' + damage + ' урона)!';
} else {
const damage = logEntry.damage || 0;
- text = who(logEntry.fromPlayer) + ' ⚔ атакует героя ' + who(logEntry.toPlayer) + ' (' + damage + ' урона)!';
+ text = who(logEntry.fromPlayer) + ' атакует героя ' + who(logEntry.toPlayer) + ' (' + damage + ' урона)!';
}
}
} else if (logEntry.type === 'spell' && logEntry.fromPlayer !== undefined && logEntry.toPlayer !== undefined) {
@@ -1112,7 +1122,7 @@
var heroCls = 'drop-target drop-target-hero' + (spellHero ? ' spell-target' : '') + (heroAb ? ' hero-ability-target' : '');
var title = spellHero ? 'Цель заклинания' : (heroAb ? 'Цель геройской способности' : 'Перетащи сюда миньона для атаки по лидеру');
return ''
- + '❤'
+ + ''
+ '' + escapeHtml(name) + ''
+ '
';
}
@@ -1124,7 +1134,7 @@
return `
-
❤
+
${escapeHtml(name)} (лидер)
${p?.health ?? 30}
@@ -2183,7 +2193,8 @@
const statusColor = room.gameStarted ? 'var(--amber)' : 'var(--cyan)';
const playersText = room.players.length > 0 ? room.players.join(', ') : 'Нет игроков';
const canJoin = !room.gameStarted && room.playerCount < room.maxPlayers;
- const actionText = room.gameStarted ? '👁 Наблюдать' : (canJoin ? '▶ Подключиться' : 'Полная');
+ const actionIcon = room.gameStarted ? '
' : (canJoin ? '
' : '');
+ const actionText = room.gameStarted ? 'Наблюдать' : (canJoin ? 'Подключиться' : 'Полная');
const actionClass = room.gameStarted ? 'btn-ghost' : (canJoin ? 'btn-primary' : 'btn-ghost');
const actionDisabled = !room.gameStarted && !canJoin;
@@ -2196,33 +2207,38 @@
Игроки: ${room.playerCount}/${room.maxPlayers}
${room.spectators > 0 ? `
Наблюдателей: ${room.spectators}
` : ''}
- ${room.hasAI ? '
🤖 ИИ
' : ''}
+ ${room.hasAI ? '
ИИ
' : ''}
${escapeHtml(playersText)}
-
+
`;
}).join('');
// Обработчики подключения к комнатам
$all('.room-item button').forEach(btn => {
- btn.addEventListener('click', function() {
- const code = this.dataset.roomCode;
- const name = ($('browse-name')?.value || '').trim() || 'Игрок';
- if (!code) return;
-
- if (!socket || !socket.connected) {
- const url = window.location.origin;
- connect(url);
- socket.once('connect', () => {
+ btn.addEventListener('click', function() {
+ const code = this.dataset.roomCode;
+ const name = ($('browse-name')?.value || '').trim() || 'Игрок';
+ if (!code) return;
+
+ if (!socket || !socket.connected) {
+ const url = window.location.origin;
+ connect(url);
+ socket.once('connect', () => {
+ socket.emit('joinRoom', { code, name });
+ });
+ } else {
socket.emit('joinRoom', { code, name });
- });
- } else {
- socket.emit('joinRoom', { code, name });
- }
+ }
+ });
});
- });
- };
+
+ // Обновляем иконки Lucide после создания кнопок
+ if (typeof lucide !== 'undefined') {
+ setTimeout(() => lucide.createIcons(), 100);
+ }
+ };
$('btn-instructions')?.addEventListener('click', () => {
$('instructions-overlay')?.classList.remove('hidden');
});
@@ -2803,9 +2819,19 @@
if (window.Music) {
window.Music.init();
}
+ // Инициализация Lucide Icons после загрузки DOM
+ if (typeof lucide !== 'undefined') {
+ lucide.createIcons();
+ // Обновляем иконки при изменении DOM
+ const observer = new MutationObserver(() => {
+ lucide.createIcons();
+ });
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
});
} else {
init();
+ if (typeof lucide !== 'undefined') lucide.createIcons();
if (window.Music) {
window.Music.init();
}
diff --git a/public/index.html b/public/index.html
index 9a7e1fc..b4f0677 100644
--- a/public/index.html
+++ b/public/index.html
@@ -11,6 +11,7 @@
+
@@ -29,8 +30,8 @@
PvP до 4 игроков · Игра с ИИ · Работает через Radmin VPN
-
-
+
+
@@ -91,7 +92,7 @@
-
+
Нажмите "Обновить список" для поиска игр
@@ -103,7 +104,7 @@
-
📚 Галерея карт
+
Галерея карт
@@ -330,7 +331,7 @@
-
⚔ Грабеж
+
Грабеж
Выберите противника и до 2 карт из его колоды
@@ -366,5 +367,18 @@
+