444 lines
26 KiB
JavaScript
444 lines
26 KiB
JavaScript
// /public/js/gameplay.js
|
||
|
||
export function initGameplay(dependencies) {
|
||
const { socket, clientState, ui } = dependencies;
|
||
const { returnToMenuButton } = ui.elements;
|
||
|
||
const attackButton = document.getElementById('button-attack');
|
||
const abilitiesGrid = document.getElementById('abilities-grid');
|
||
|
||
// Инициализируем флаг в clientState, если он еще не существует (лучше делать в main.js)
|
||
if (typeof clientState.isActionInProgress === 'undefined') {
|
||
clientState.isActionInProgress = false;
|
||
}
|
||
|
||
// --- Вспомогательные функции ---
|
||
function enableGameControls(enableAttack = true, enableAbilities = true) {
|
||
// console.log(`[GP] enableGameControls called. enableAttack: ${enableAttack}, enableAbilities: ${enableAbilities}, isActionInProgress: ${clientState.isActionInProgress}`);
|
||
if (clientState.isActionInProgress) {
|
||
if (attackButton) attackButton.disabled = true;
|
||
if (abilitiesGrid) {
|
||
const config = window.GAME_CONFIG || {};
|
||
const cls = config.CSS_CLASS_ABILITY_BUTTON || 'ability-button';
|
||
abilitiesGrid.querySelectorAll(`.${cls}`).forEach(b => { b.disabled = true; });
|
||
}
|
||
// console.log(`[GP] Action in progress, controls remain disabled.`);
|
||
if (window.gameUI?.updateUI) requestAnimationFrame(() => window.gameUI.updateUI());
|
||
return;
|
||
}
|
||
|
||
if (attackButton) attackButton.disabled = !enableAttack;
|
||
if (abilitiesGrid) {
|
||
const config = window.GAME_CONFIG || {};
|
||
const cls = config.CSS_CLASS_ABILITY_BUTTON || 'ability-button';
|
||
abilitiesGrid.querySelectorAll(`.${cls}`).forEach(b => { b.disabled = !enableAbilities; });
|
||
}
|
||
// console.log(`[GP] Controls set. Attack disabled: ${attackButton ? attackButton.disabled : 'N/A'}`);
|
||
if (window.gameUI?.updateUI) {
|
||
requestAnimationFrame(() => window.gameUI.updateUI()); // Обновляем UI, чтобы 반영 반영反映 изменения в disabled
|
||
}
|
||
}
|
||
|
||
function disableGameControls() {
|
||
// console.log(`[GP] disableGameControls called.`);
|
||
if (attackButton) attackButton.disabled = true;
|
||
if (abilitiesGrid) {
|
||
const config = window.GAME_CONFIG || {};
|
||
const cls = config.CSS_CLASS_ABILITY_BUTTON || 'ability-button';
|
||
abilitiesGrid.querySelectorAll(`.${cls}`).forEach(b => { b.disabled = true; });
|
||
}
|
||
if (window.gameUI?.updateUI) {
|
||
requestAnimationFrame(() => window.gameUI.updateUI()); // Обновляем UI, чтобы 반영 반영反映 изменения в disabled
|
||
}
|
||
}
|
||
|
||
function initializeAbilityButtons() {
|
||
if (!abilitiesGrid || !window.gameUI || !window.GAME_CONFIG) {
|
||
if (abilitiesGrid) abilitiesGrid.innerHTML = '<p class="placeholder-text">Ошибка загрузки способностей.</p>';
|
||
return;
|
||
}
|
||
abilitiesGrid.innerHTML = '';
|
||
const config = window.GAME_CONFIG;
|
||
const abilitiesToDisplay = clientState.playerAbilitiesServer;
|
||
const baseStatsForResource = clientState.playerBaseStatsServer;
|
||
|
||
if (!abilitiesToDisplay || abilitiesToDisplay.length === 0 || !baseStatsForResource) {
|
||
abilitiesGrid.innerHTML = '<p class="placeholder-text">Нет доступных способностей.</p>';
|
||
return;
|
||
}
|
||
|
||
const resourceName = baseStatsForResource.resourceName || "Ресурс";
|
||
const abilityButtonClass = config.CSS_CLASS_ABILITY_BUTTON || 'ability-button';
|
||
|
||
abilitiesToDisplay.forEach(ability => {
|
||
const button = document.createElement('button');
|
||
button.id = `ability-btn-${ability.id}`;
|
||
button.classList.add(abilityButtonClass);
|
||
button.dataset.abilityId = ability.id;
|
||
let cooldown = ability.cooldown;
|
||
let cooldownText = (typeof cooldown === 'number' && cooldown > 0) ? ` (КД: ${cooldown} х.)` : "";
|
||
let title = `${ability.name} (${ability.cost} ${resourceName})${cooldownText} - ${ability.description || 'Нет описания'}`;
|
||
button.setAttribute('title', title);
|
||
const nameSpan = document.createElement('span'); nameSpan.classList.add('ability-name'); nameSpan.textContent = ability.name; button.appendChild(nameSpan);
|
||
const descSpan = document.createElement('span'); descSpan.classList.add('ability-desc'); descSpan.textContent = `(${ability.cost} ${resourceName})`; button.appendChild(descSpan);
|
||
const cdDisplay = document.createElement('span'); cdDisplay.classList.add('ability-cooldown-display'); cdDisplay.style.display = 'none'; button.appendChild(cdDisplay);
|
||
button.addEventListener('click', handleAbilityButtonClick);
|
||
abilitiesGrid.appendChild(button);
|
||
});
|
||
const placeholder = abilitiesGrid.querySelector('.placeholder-text');
|
||
if (placeholder) placeholder.remove();
|
||
}
|
||
|
||
function handleAbilityButtonClick(event) {
|
||
const abilityId = event.currentTarget.dataset.abilityId;
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] handleAbilityButtonClick. AbilityID: ${abilityId}, isActionInProgress: ${clientState.isActionInProgress}`);
|
||
|
||
if (clientState.isLoggedIn &&
|
||
clientState.isInGame &&
|
||
clientState.currentGameId &&
|
||
abilityId &&
|
||
clientState.currentGameState &&
|
||
!clientState.currentGameState.isGameOver &&
|
||
!clientState.isActionInProgress) { // <--- ПРОВЕРКА ФЛАГА
|
||
|
||
console.log(`[CLIENT ${username}] Emitting playerAction (ability: ${abilityId}). Setting isActionInProgress = true.`);
|
||
clientState.isActionInProgress = true; // <--- УСТАНОВКА ФЛАГА
|
||
disableGameControls(); // <--- БЛОКИРОВКА СРАЗУ
|
||
socket.emit('playerAction', { actionType: 'ability', abilityId: abilityId });
|
||
} else {
|
||
console.warn(`[CLIENT ${username}] Cannot perform ability action. Conditions not met or action in progress. InGame: ${clientState.isInGame}, GameOver: ${clientState.currentGameState?.isGameOver}, ActionInProgress: ${clientState.isActionInProgress}`);
|
||
}
|
||
}
|
||
|
||
// --- Обработчики событий DOM ---
|
||
if (attackButton) {
|
||
attackButton.addEventListener('click', () => {
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] Attack button clicked. isActionInProgress: ${clientState.isActionInProgress}`);
|
||
|
||
if (clientState.isLoggedIn &&
|
||
clientState.isInGame &&
|
||
clientState.currentGameId &&
|
||
clientState.currentGameState &&
|
||
!clientState.currentGameState.isGameOver &&
|
||
!clientState.isActionInProgress) { // <--- ПРОВЕРКА ФЛАГА
|
||
|
||
console.log(`[CLIENT ${username}] Emitting playerAction (attack). Setting isActionInProgress = true.`);
|
||
clientState.isActionInProgress = true; // <--- УСТАНОВКА ФЛАГА
|
||
disableGameControls(); // <--- БЛОКИРОВКА СРАЗУ
|
||
socket.emit('playerAction', { actionType: 'attack' });
|
||
} else {
|
||
console.warn(`[CLIENT ${username}] Cannot perform attack action. Conditions not met or action in progress. InGame: ${clientState.isInGame}, GameOver: ${clientState.currentGameState?.isGameOver}, ActionInProgress: ${clientState.isActionInProgress}`);
|
||
}
|
||
});
|
||
}
|
||
|
||
if (returnToMenuButton) {
|
||
returnToMenuButton.addEventListener('click', () => {
|
||
if (!clientState.isLoggedIn) {
|
||
ui.showAuthScreen();
|
||
return;
|
||
}
|
||
returnToMenuButton.disabled = true; // Блокируем сразу, чтобы избежать двойных кликов
|
||
clientState.isActionInProgress = false; // Сбрасываем на всякий случай, если покидаем игру
|
||
clientState.isInGame = false;
|
||
disableGameControls();
|
||
ui.showGameSelectionScreen(clientState.loggedInUsername);
|
||
});
|
||
}
|
||
|
||
|
||
// --- ОБЩИЙ ОБРАБОТЧИК ДЛЯ ЗАПУСКА/ВОССТАНОВЛЕНИЯ ИГРЫ ---
|
||
function handleGameDataReceived(data, eventName = "unknown") {
|
||
if (!clientState.isLoggedIn) {
|
||
console.warn(`[CLIENT] handleGameDataReceived (${eventName}) called, but client not logged in. Ignoring.`);
|
||
return;
|
||
}
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] handleGameDataReceived from event: ${eventName}. GameID: ${data.gameId}, YourPlayerID: ${data.yourPlayerId}, GS.isPlayerTurn: ${data.initialGameState?.isPlayerTurn || data.gameState?.isPlayerTurn}`);
|
||
|
||
clientState.isActionInProgress = false; // <--- СБРОС ФЛАГА при получении нового полного состояния
|
||
|
||
clientState.currentGameId = data.gameId;
|
||
clientState.myPlayerId = data.yourPlayerId;
|
||
clientState.currentGameState = data.initialGameState || data.gameState;
|
||
clientState.playerBaseStatsServer = data.playerBaseStats;
|
||
clientState.opponentBaseStatsServer = data.opponentBaseStats;
|
||
clientState.playerAbilitiesServer = data.playerAbilities;
|
||
clientState.opponentAbilitiesServer = data.opponentAbilities;
|
||
clientState.myCharacterKey = data.playerBaseStats?.characterKey;
|
||
clientState.opponentCharacterKey = data.opponentBaseStats?.characterKey;
|
||
|
||
if (clientState.currentGameState && !clientState.currentGameState.isGameOver) {
|
||
clientState.isInGame = true;
|
||
} else if (clientState.currentGameState && clientState.currentGameState.isGameOver) {
|
||
clientState.isInGame = false;
|
||
}
|
||
|
||
if (data.clientConfig) {
|
||
window.GAME_CONFIG = { ...window.GAME_CONFIG, ...data.clientConfig };
|
||
} else if (!window.GAME_CONFIG) {
|
||
window.GAME_CONFIG = { PLAYER_ID: 'player', OPPONENT_ID: 'opponent', CSS_CLASS_HIDDEN: 'hidden' }; // Базовый конфиг
|
||
}
|
||
ui.updateGlobalWindowVariablesForUI();
|
||
|
||
const gameWrapperElement = document.querySelector('.game-wrapper');
|
||
if (clientState.isInGame && clientState.currentGameState && !clientState.currentGameState.isGameOver) {
|
||
const isGameWrapperVisible = gameWrapperElement && (gameWrapperElement.style.display === 'flex' || getComputedStyle(gameWrapperElement).display === 'flex');
|
||
if (!isGameWrapperVisible) {
|
||
ui.showGameScreen();
|
||
}
|
||
}
|
||
|
||
initializeAbilityButtons();
|
||
|
||
if (window.gameUI?.uiElements?.log?.list) {
|
||
window.gameUI.uiElements.log.list.innerHTML = '';
|
||
}
|
||
if (window.gameUI?.addToLog && data.log) {
|
||
data.log.forEach(logEntry => {
|
||
window.gameUI.addToLog(logEntry.message, logEntry.type);
|
||
});
|
||
}
|
||
|
||
requestAnimationFrame(() => {
|
||
if (window.gameUI?.updateUI) {
|
||
window.gameUI.updateUI();
|
||
}
|
||
if (clientState.isInGame && clientState.currentGameState && !clientState.currentGameState.isGameOver && window.GAME_CONFIG) {
|
||
const config = window.GAME_CONFIG;
|
||
const isMyActualTurn = clientState.myPlayerId &&
|
||
((clientState.currentGameState.isPlayerTurn && clientState.myPlayerId === config.PLAYER_ID) ||
|
||
(!clientState.currentGameState.isPlayerTurn && clientState.myPlayerId === config.OPPONENT_ID));
|
||
|
||
console.log(`[CLIENT ${username}] handleGameDataReceived - Determining controls. isMyActualTurn: ${isMyActualTurn}`);
|
||
if (isMyActualTurn) {
|
||
enableGameControls();
|
||
} else {
|
||
disableGameControls();
|
||
}
|
||
} else if (clientState.currentGameState && clientState.currentGameState.isGameOver) {
|
||
console.log(`[CLIENT ${username}] handleGameDataReceived - Game is over, disabling controls.`);
|
||
disableGameControls();
|
||
}
|
||
});
|
||
|
||
if (clientState.currentGameState && clientState.currentGameState.isGameOver) {
|
||
// Обработка gameOver уже есть в своем обработчике
|
||
} else if (eventName === 'gameStarted' || eventName === 'gameState (reconnect)') {
|
||
console.log(`[CLIENT ${username}] ${eventName} - Clearing game status message because it's a fresh game/state load.`);
|
||
ui.setGameStatusMessage("");
|
||
} else {
|
||
if (clientState.isInGame) {
|
||
// Если это просто gameStateUpdate, и игра активна, убедимся, что нет сообщения об ожидании
|
||
const statusMsgElement = document.getElementById('game-status-message');
|
||
const currentStatusText = statusMsgElement ? statusMsgElement.textContent : "";
|
||
if (!currentStatusText.toLowerCase().includes("отключился")) { // Не стираем сообщение об отключении оппонента
|
||
ui.setGameStatusMessage("");
|
||
}
|
||
}
|
||
}
|
||
if (clientState.currentGameState && clientState.currentGameState.isGameOver) {
|
||
if (window.gameUI?.showGameOver && !document.getElementById('game-over-screen').classList.contains(window.GAME_CONFIG?.CSS_CLASS_HIDDEN || 'hidden')) {
|
||
// Экран уже показан
|
||
} else if (window.gameUI?.showGameOver) {
|
||
let playerWon = false;
|
||
if (data.winnerId) {
|
||
playerWon = data.winnerId === clientState.myPlayerId;
|
||
} else if (clientState.currentGameState.player && clientState.currentGameState.opponent) {
|
||
// Дополнительная логика определения победителя, если winnerId нет (маловероятно при корректной работе сервера)
|
||
if (clientState.currentGameState.player.currentHp > 0 && clientState.currentGameState.opponent.currentHp <=0) {
|
||
playerWon = clientState.myPlayerId === clientState.currentGameState.player.id;
|
||
} else if (clientState.currentGameState.opponent.currentHp > 0 && clientState.currentGameState.player.currentHp <=0) {
|
||
playerWon = clientState.myPlayerId === clientState.currentGameState.opponent.id;
|
||
}
|
||
}
|
||
window.gameUI.showGameOver(playerWon, data.reason || "Игра завершена", clientState.opponentCharacterKey || data.loserCharacterKey, { finalGameState: clientState.currentGameState, ...data });
|
||
}
|
||
if (returnToMenuButton) returnToMenuButton.disabled = false;
|
||
}
|
||
}
|
||
|
||
|
||
// --- Обработчики событий Socket.IO ---
|
||
socket.on('gameStarted', (data) => {
|
||
handleGameDataReceived(data, 'gameStarted');
|
||
});
|
||
|
||
socket.on('gameState', (data) => {
|
||
handleGameDataReceived(data, 'gameState (reconnect)');
|
||
});
|
||
|
||
socket.on('gameStateUpdate', (data) => {
|
||
if (!clientState.isLoggedIn || !clientState.isInGame || !clientState.currentGameId || !window.GAME_CONFIG) return;
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] Event: gameStateUpdate. GS.isPlayerTurn: ${data.gameState?.isPlayerTurn}`);
|
||
|
||
clientState.isActionInProgress = false; // <--- СБРОС ФЛАГА
|
||
clientState.currentGameState = data.gameState;
|
||
ui.updateGlobalWindowVariablesForUI();
|
||
|
||
if (window.gameUI?.updateUI) {
|
||
requestAnimationFrame(() => {
|
||
window.gameUI.updateUI();
|
||
if (clientState.isInGame && clientState.currentGameState && !clientState.currentGameState.isGameOver && window.GAME_CONFIG) {
|
||
const config = window.GAME_CONFIG;
|
||
const isMyActualTurn = clientState.myPlayerId &&
|
||
((clientState.currentGameState.isPlayerTurn && clientState.myPlayerId === config.PLAYER_ID) ||
|
||
(!clientState.currentGameState.isPlayerTurn && clientState.myPlayerId === config.OPPONENT_ID));
|
||
|
||
console.log(`[CLIENT ${username}] gameStateUpdate - Determining controls. isMyActualTurn: ${isMyActualTurn}`);
|
||
if (isMyActualTurn) {
|
||
enableGameControls();
|
||
} else {
|
||
disableGameControls();
|
||
}
|
||
|
||
const statusMsgElement = document.getElementById('game-status-message');
|
||
const currentStatusText = statusMsgElement ? statusMsgElement.textContent : "";
|
||
if (!currentStatusText.toLowerCase().includes("отключился")) {
|
||
ui.setGameStatusMessage("");
|
||
}
|
||
|
||
} else if (clientState.currentGameState && clientState.currentGameState.isGameOver) {
|
||
console.log(`[CLIENT ${username}] gameStateUpdate - Game is over, disabling controls.`);
|
||
disableGameControls();
|
||
}
|
||
});
|
||
}
|
||
|
||
if (window.gameUI?.addToLog && data.log) {
|
||
data.log.forEach(log => window.gameUI.addToLog(log.message, log.type));
|
||
}
|
||
});
|
||
|
||
socket.on('logUpdate', (data) => {
|
||
if (!clientState.isLoggedIn || !clientState.isInGame || !clientState.currentGameId || !window.GAME_CONFIG) return;
|
||
// const username = clientState.loggedInUsername || 'N/A';
|
||
// console.log(`[CLIENT ${username}] Event: logUpdate. Logs:`, data.log);
|
||
if (window.gameUI?.addToLog && data.log) {
|
||
data.log.forEach(log => window.gameUI.addToLog(log.message, log.type));
|
||
}
|
||
});
|
||
|
||
socket.on('gameOver', (data) => {
|
||
if (!clientState.isLoggedIn || !clientState.currentGameId || !window.GAME_CONFIG) {
|
||
if (!clientState.currentGameId && clientState.isLoggedIn) socket.emit('requestGameState');
|
||
else if (!clientState.isLoggedIn) ui.showAuthScreen();
|
||
return;
|
||
}
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] Event: gameOver. WinnerID: ${data.winnerId}, Reason: ${data.reason}`);
|
||
|
||
clientState.isActionInProgress = false; // <--- СБРОС ФЛАГА
|
||
const playerWon = data.winnerId === clientState.myPlayerId;
|
||
clientState.currentGameState = data.finalGameState;
|
||
clientState.isInGame = false;
|
||
|
||
ui.updateGlobalWindowVariablesForUI();
|
||
|
||
if (window.gameUI?.updateUI) requestAnimationFrame(() => window.gameUI.updateUI());
|
||
if (window.gameUI?.addToLog && data.log) {
|
||
data.log.forEach(log => window.gameUI.addToLog(log.message, log.type));
|
||
}
|
||
if (window.gameUI?.showGameOver) {
|
||
const oppKey = clientState.opponentCharacterKey || data.loserCharacterKey;
|
||
window.gameUI.showGameOver(playerWon, data.reason, oppKey, data);
|
||
}
|
||
if (returnToMenuButton) returnToMenuButton.disabled = false;
|
||
|
||
if (window.gameUI?.updateTurnTimerDisplay) {
|
||
window.gameUI.updateTurnTimerDisplay(null, false, clientState.currentGameState?.gameMode);
|
||
}
|
||
disableGameControls();
|
||
});
|
||
|
||
socket.on('opponentDisconnected', (data) => {
|
||
if (!clientState.isLoggedIn || !clientState.isInGame || !clientState.currentGameId || !window.GAME_CONFIG) return;
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] Event: opponentDisconnected. PlayerID: ${data.disconnectedPlayerId}`);
|
||
const name = data.disconnectedCharacterName || clientState.opponentBaseStatsServer?.name || 'Противник';
|
||
|
||
if (clientState.currentGameState && !clientState.currentGameState.isGameOver) {
|
||
ui.setGameStatusMessage(`Противник (${name}) отключился. Ожидание...`, true);
|
||
disableGameControls();
|
||
}
|
||
});
|
||
|
||
socket.on('playerReconnected', (data) => { // Обработчик события, что оппонент переподключился
|
||
if (!clientState.isLoggedIn || !clientState.isInGame || !clientState.currentGameId || !window.GAME_CONFIG) return;
|
||
const username = clientState.loggedInUsername || 'N/A';
|
||
console.log(`[CLIENT ${username}] Event: playerReconnected. PlayerID: ${data.reconnectedPlayerId}, Name: ${data.reconnectedPlayerName}`);
|
||
// const name = data.reconnectedPlayerName || clientState.opponentBaseStatsServer?.name || 'Противник';
|
||
|
||
if (clientState.currentGameState && !clientState.currentGameState.isGameOver) {
|
||
// Сообщение о переподключении оппонента обычно приходит через 'logUpdate'
|
||
// Но если нужно немедленно убрать статус "Ожидание...", можно сделать здесь:
|
||
const statusMsgElement = document.getElementById('game-status-message');
|
||
const currentStatusText = statusMsgElement ? statusMsgElement.textContent : "";
|
||
if (currentStatusText.toLowerCase().includes("отключился")) {
|
||
ui.setGameStatusMessage(""); // Очищаем сообщение об ожидании
|
||
}
|
||
// Логика enable/disableGameControls будет вызвана следующим gameStateUpdate или turnTimerUpdate
|
||
}
|
||
});
|
||
|
||
|
||
socket.on('turnTimerUpdate', (data) => {
|
||
if (!clientState.isInGame || !clientState.currentGameState || !window.GAME_CONFIG) {
|
||
if (window.gameUI?.updateTurnTimerDisplay && clientState.currentGameState && !clientState.currentGameState.isGameOver) {
|
||
window.gameUI.updateTurnTimerDisplay(null, false, clientState.currentGameState.gameMode);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (clientState.currentGameState.isGameOver) {
|
||
if (window.gameUI?.updateTurnTimerDisplay) {
|
||
window.gameUI.updateTurnTimerDisplay(null, false, clientState.currentGameState.gameMode);
|
||
}
|
||
// disableGameControls() уже должен быть вызван в gameOver
|
||
return;
|
||
}
|
||
// const username = clientState.loggedInUsername || 'N/A';
|
||
// console.log(`[CLIENT ${username}] Event: turnTimerUpdate. Remaining: ${data.remainingTime}, isPlayerTurnForTimer: ${data.isPlayerTurn}, isPaused: ${data.isPaused}`);
|
||
|
||
|
||
if (window.gameUI && typeof window.gameUI.updateTurnTimerDisplay === 'function') {
|
||
const config = window.GAME_CONFIG;
|
||
const isMyTurnForTimer = clientState.myPlayerId && clientState.currentGameState &&
|
||
((data.isPlayerTurn && clientState.myPlayerId === config.PLAYER_ID) || // Серверное data.isPlayerTurn здесь авторитетно для таймера
|
||
(!data.isPlayerTurn && clientState.myPlayerId === config.OPPONENT_ID));
|
||
|
||
window.gameUI.updateTurnTimerDisplay(data.remainingTime, isMyTurnForTimer, clientState.currentGameState.gameMode);
|
||
|
||
// Если игра НЕ на паузе (серверной или клиентской из-за дисконнекта оппонента)
|
||
if (!data.isPaused) {
|
||
// Управление кнопками должно быть на основе isPlayerTurn из gameState, а не из turnTimerUpdate
|
||
// gameStateUpdate обработает это. Здесь только если нужно немедленно реагировать на isPlayerTurn из таймера,
|
||
// но это может привести к конфликтам с gameState.isPlayerTurn.
|
||
// Лучше положиться на gameStateUpdate.
|
||
// Однако, если ТАЙМЕР НЕ ПРИОСТАНОВЛЕН и это МОЙ ХОД по таймеру, то кнопки должны быть активны.
|
||
// Это может быть полезно, если gameStateUpdate запаздывает.
|
||
if (isMyTurnForTimer && !clientState.currentGameState.isGameOver) { // Дополнительная проверка на GameOver
|
||
enableGameControls();
|
||
} else if (!isMyTurnForTimer && !clientState.currentGameState.isGameOver){ // Иначе, если не мой ход
|
||
disableGameControls();
|
||
}
|
||
|
||
const statusMsgElement = document.getElementById('game-status-message');
|
||
const currentStatusText = statusMsgElement ? statusMsgElement.textContent : "";
|
||
if (!currentStatusText.toLowerCase().includes("отключился") && !clientState.currentGameState.isGameOver) {
|
||
// console.log(`[CLIENT ${username}] turnTimerUpdate - Clearing game status message as timer is active and not paused.`);
|
||
ui.setGameStatusMessage("");
|
||
}
|
||
} else { // Если игра на паузе (по данным таймера)
|
||
// console.log(`[CLIENT ${username}] turnTimerUpdate - Game is paused, disabling controls.`);
|
||
disableGameControls(); // Отключаем управление, если таймер говорит, что игра на паузе
|
||
}
|
||
}
|
||
});
|
||
|
||
// Начальная деактивация (на всякий случай, хотя showAuthScreen/showGameSelectionScreen должны это делать)
|
||
disableGameControls();
|
||
} |