bc/public/js/gameSetup.js

199 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// /public/js/gameSetup.js
export function initGameSetup(dependencies) {
const { socket, clientState, ui } = dependencies;
const {
createAIGameButton, createPvPGameButton, joinPvPGameButton,
findRandomPvPGameButton, gameIdInput, availableGamesDiv, pvpCharacterRadios
} = ui.elements;
// --- Вспомогательные функции ---
function getSelectedCharacterKey() {
let selectedKey = 'elena'; // Значение по умолчанию
if (pvpCharacterRadios) {
pvpCharacterRadios.forEach(radio => {
if (radio.checked) {
selectedKey = radio.value;
}
});
}
return selectedKey;
}
function updateAvailableGamesList(games) {
if (!availableGamesDiv) return;
availableGamesDiv.innerHTML = '<h3>Доступные PvP игры:</h3>';
if (games && games.length > 0) {
const ul = document.createElement('ul');
games.forEach(game => {
if (game && game.id) {
const li = document.createElement('li');
// Отображаем только часть ID для краткости
li.textContent = `ID: ${game.id.substring(0, 8)}... - ${game.status || 'Ожидает игрока'}`;
const joinBtn = document.createElement('button');
joinBtn.textContent = 'Присоединиться';
joinBtn.dataset.gameId = game.id;
// Деактивация кнопки "Присоединиться" для своих игр
if (clientState.isLoggedIn && clientState.myUserId && game.ownerIdentifier === clientState.myUserId) {
joinBtn.disabled = true;
joinBtn.title = "Вы не можете присоединиться к своей же ожидающей игре.";
} else {
joinBtn.disabled = false;
}
joinBtn.addEventListener('click', (e) => {
if (!clientState.isLoggedIn) {
ui.setGameStatusMessage("Пожалуйста, войдите, чтобы присоединиться к игре.", true);
return;
}
if (e.target.disabled) return; // Не обрабатывать клик по отключенной кнопке
ui.disableSetupButtons(); // Блокируем все кнопки выбора игры
socket.emit('joinGame', { gameId: e.target.dataset.gameId });
ui.setGameStatusMessage(`Присоединение к игре ${e.target.dataset.gameId.substring(0, 8)}...`);
});
li.appendChild(joinBtn);
ul.appendChild(li);
}
});
availableGamesDiv.appendChild(ul);
} else {
availableGamesDiv.innerHTML += '<p>Нет доступных игр. Создайте свою!</p>';
}
ui.enableSetupButtons(); // Включаем основные кнопки создания/поиска после обновления списка
}
// --- Обработчики событий DOM ---
if (createAIGameButton) {
createAIGameButton.addEventListener('click', () => {
if (!clientState.isLoggedIn) {
ui.setGameStatusMessage("Пожалуйста, войдите, чтобы создать игру.", true);
return;
}
ui.disableSetupButtons();
// Для AI игры персонаж может быть фиксированным или выбираемым
// В вашем client.js был 'elena', оставим так
socket.emit('createGame', { mode: 'ai', characterKey: 'elena' });
ui.setGameStatusMessage("Создание игры против AI...");
});
}
if (createPvPGameButton) {
createPvPGameButton.addEventListener('click', () => {
if (!clientState.isLoggedIn) {
ui.setGameStatusMessage("Пожалуйста, войдите, чтобы создать игру.", true);
return;
}
ui.disableSetupButtons();
const characterKey = getSelectedCharacterKey();
socket.emit('createGame', { mode: 'pvp', characterKey: characterKey });
ui.setGameStatusMessage("Создание PvP игры...");
});
}
if (joinPvPGameButton) {
joinPvPGameButton.addEventListener('click', () => {
if (!clientState.isLoggedIn) {
ui.setGameStatusMessage("Пожалуйста, войдите, чтобы присоединиться к игре.", true);
return;
}
const gameId = gameIdInput ? gameIdInput.value.trim() : '';
if (gameId) {
ui.disableSetupButtons();
socket.emit('joinGame', { gameId: gameId });
ui.setGameStatusMessage(`Присоединение к игре ${gameId}...`);
} else {
ui.setGameStatusMessage("Введите ID игры, чтобы присоединиться.", true);
}
});
}
if (findRandomPvPGameButton) {
findRandomPvPGameButton.addEventListener('click', () => {
if (!clientState.isLoggedIn) {
ui.setGameStatusMessage("Пожалуйста, войдите, чтобы найти игру.", true);
return;
}
ui.disableSetupButtons();
const characterKey = getSelectedCharacterKey();
socket.emit('findRandomGame', { characterKey: characterKey });
ui.setGameStatusMessage("Поиск случайной PvP игры...");
});
}
// --- Обработчики событий Socket.IO ---
// gameCreated: Сервер присылает это после успешного createGame
// Это событие может быть важным для установки currentGameId и myPlayerId
// перед тем, как придет gameStarted или waitingForOpponent.
socket.on('gameCreated', (data) => {
if (!clientState.isLoggedIn) return; // Игнорируем, если не залогинены
console.log('[GameSetup] Game created by this client:', data);
clientState.currentGameId = data.gameId;
clientState.myPlayerId = data.yourPlayerId; // Сервер должен прислать роль создателя
ui.updateGlobalWindowVariablesForUI(); // Обновляем глобальные переменные для ui.js
// Если это PvP игра, обычно сервер следом пришлет 'waitingForOpponent'
// Если AI, то сразу 'gameStarted'
// На этом этапе UI не меняем кардинально, ждем следующего события.
// ui.setGameStatusMessage(`Игра ${data.gameId.substring(0,8)} создана. Ожидание...`);
// Кнопки уже должны быть заблокированы ui.disableSetupButtons()
});
socket.on('availablePvPGamesList', (games) => {
if (!clientState.isLoggedIn) return; // Только для залогиненных пользователей
updateAvailableGamesList(games);
});
// Это событие приходит, когда игрок искал случайную игру, но свободных не было,
// и сервер создал новую игру для этого игрока.
socket.on('noPendingGamesFound', (data) => {
if (!clientState.isLoggedIn) return;
ui.setGameStatusMessage(data.message || "Свободных игр не найдено. Создана новая для вас. Ожидание оппонента...");
updateAvailableGamesList([]); // Очищаем список доступных игр, так как мы уже в созданной
// clientState.currentGameId и clientState.myPlayerId должны были быть установлены
// через событие 'gameCreated', которое сервер должен прислать перед 'noPendingGamesFound'.
// Если 'gameCreated' не присылается в этом сценарии, нужно будет получать gameId и yourPlayerId из data 'noPendingGamesFound'.
if (data.gameId) clientState.currentGameId = data.gameId;
if (data.yourPlayerId) clientState.myPlayerId = data.yourPlayerId;
ui.updateGlobalWindowVariablesForUI();
clientState.isInGame = false; // Мы еще не в активной фазе боя, а в ожидании
// ui.disableGameControls(); // Будет вызвано из gameplay.js, если он уже был инициализирован
// или неактуально, так как мы не на игровом экране
ui.disableSetupButtons(); // Мы в ожидающей игре, кнопки выбора не нужны
// Можно оставить кнопку "Создать PvP" активной для возможности "отменить" и создать другую,
// но это усложнит логику. Пока блокируем все.
// Если есть таймер, его нужно сбросить или показать "Ожидание"
if (window.gameUI?.updateTurnTimerDisplay) {
window.gameUI.updateTurnTimerDisplay(null, false, 'pvp'); // Таймер неактивен в ожидании
}
});
// waitingForOpponent: Когда PvP игра создана и ожидает второго игрока
socket.on('waitingForOpponent', () => {
if (!clientState.isLoggedIn) return;
ui.setGameStatusMessage("Ожидание присоединения оппонента...");
// clientState.isInGame = false; // Уже должно быть false или будет установлено при gameStarted
// ui.disableGameControls(); // не на игровом экране
ui.disableSetupButtons(); // Блокируем кнопки создания/присоединения
// Можно оставить кнопку "Создать PvP" или добавить кнопку "Отменить ожидание",
// но это требует дополнительной логики на сервере и клиенте.
// if (ui.elements.createPvPGameButton) ui.elements.createPvPGameButton.disabled = false;
if (window.gameUI?.updateTurnTimerDisplay) {
window.gameUI.updateTurnTimerDisplay(null, false, 'pvp');
}
});
// Примечание: gameNotFound обрабатывается в main.js, так как он может сбросить
// игрока на экран выбора игры или даже на экран логина.
}