diff --git a/game.js b/game.js index 3822c0b..2a13fb7 100644 --- a/game.js +++ b/game.js @@ -2395,63 +2395,228 @@ registerProcessor('voice-playback', VoicePlaybackProcessor); inventoryPanel.style.display = 'none'; }; - // Кнопка сохранения игры (только для одиночного режима) - const saveBtn = document.getElementById('saveBtn'); - saveBtn.onclick = () => { - playSound('click'); - saveGame(); - customAlert('Игра сохранена!'); - }; - - // Кнопка сброса игры (удаление сохранения и создание нового мира) - const resetBtn = document.getElementById('resetBtn'); - resetBtn.onclick = () => { - customConfirm('Вы уверены, что хотите удалить сохранение и начать новую игру?', () => { - playSound('click'); - - // Удаляем сохранение из localStorage - try { - localStorage.removeItem(SAVE_KEY); - console.log('Сохранение удалено из localStorage'); - } catch (e) { - console.warn('Ошибка удаления сохранения:', e); - } - - // Сбрасываем in-memory сохранение - inMemorySave = null; - - // Генерируем новый worldId - worldId = Math.random().toString(36).substring(2, 10); - console.log('Новый worldId после сброса:', worldId); - - // Обновляем URL - try { - const newUrl = new URL(window.location.href); - newUrl.searchParams.set('world', worldId); - const newUrlString = newUrl.toString(); - - if (typeof window.history !== 'undefined' && typeof window.history.replaceState === 'function') { - window.history.replaceState(null, '', newUrlString); - console.log('URL обновлён:', newUrlString); - } - } catch (e) { - console.error('Ошибка обновления URL:', e); - } - - // Перезагружаем страницу - location.reload(); + // Меню ⋯ (dropdown) + let dropdownOpen = false; + const menuBtn = document.getElementById('menuBtn'); + const menuDropdown = document.getElementById('menuDropdown'); + const saveItem = document.getElementById('saveItem'); + const resetItem = document.getElementById('resetItem'); + const marketItem = document.getElementById('marketItem'); + const settingsItem = document.getElementById('settingsItem'); + + if (menuBtn) { + menuBtn.onclick = null; + menuBtn.addEventListener('click', (e) => { + e.stopPropagation(); + dropdownOpen = !dropdownOpen; + menuDropdown.classList.toggle('open', dropdownOpen); }); - }; - + } + document.addEventListener('click', () => { + if (dropdownOpen) { + dropdownOpen = false; + menuDropdown.classList.remove('open'); + } + }); + menuDropdown && menuDropdown.addEventListener('click', (e) => e.stopPropagation()); + + // 💾 Сохранить + if (saveItem) { + saveItem.addEventListener('click', () => { + playSound('click'); + saveGame(); + dropdownOpen = false; + menuDropdown.classList.remove('open'); + customAlert('Игра сохранена!'); + }); + } + + // 🔄 Новый мир + if (resetItem) { + resetItem.addEventListener('click', () => { + customConfirm('Вы уверены, что хотите удалить сохранение и начать новую игру?', () => { + playSound('click'); + try { + localStorage.removeItem(SAVE_KEY); + console.log('Сохранение удалено из localStorage'); + } catch (e) { + console.warn('Ошибка удаления сохранения:', e); + } + inMemorySave = null; + worldId = Math.random().toString(36).substring(2, 10); + console.log('Новый worldId после сброса:', worldId); + try { + const newUrl = new URL(window.location.href); + newUrl.searchParams.set('world', worldId); + if (typeof window.history !== 'undefined' && typeof window.history.replaceState === 'function') { + window.history.replaceState(null, '', newUrl.toString()); + } + } catch (e) { + console.error('Ошибка обновления URL:', e); + } + location.reload(); + }); + }); + } + + // 🏪 Рынок + if (marketItem) { + marketItem.addEventListener('click', () => { + dropdownOpen = false; + menuDropdown.classList.remove('open'); + toggleMarket(); + }); + } + + // ⚙ Настройки + if (settingsItem) { + settingsItem.addEventListener('click', () => { + dropdownOpen = false; + menuDropdown.classList.remove('open'); + toggleSettingsPanel(); + }); + } + // Показываем кнопку сохранения только если играем одни function updateSaveButtonVisibility() { - if (isMultiplayer && otherPlayers.size > 0) { - saveBtn.style.display = 'none'; - } else { - saveBtn.style.display = 'flex'; + if (saveItem) { + saveItem.style.display = (isMultiplayer && otherPlayers.size > 0) ? 'none' : 'block'; } } + // ==================== РЫНОК ==================== + const marketPanel = document.getElementById('marketPanel'); + const marketClose = document.getElementById('marketClose'); + const marketContent = document.getElementById('marketContent'); + + if (marketClose) { + marketClose.addEventListener('click', () => { marketPanel.style.display = 'none'; }); + } + + function toggleMarket() { + if (marketPanel.style.display === 'none' || !marketPanel.style.display) { + openMarket(); + } else { + marketPanel.style.display = 'none'; + } + } + + function openMarket() { + marketPanel.style.display = 'block'; + renderMarket(); + } + + let marketOrders = []; // локальный кэш ордеров + + function renderMarket() { + if (!socket) { + marketContent.innerHTML = '
Подключение к серверу...
'; + return; + } + socket.emit('market_list', {}, (orders) => { + if (!orders || !orders.length) { + marketOrders = []; + marketContent.innerHTML = + 'Предложений пока нет
' + + 'Отключите, чтобы заморозить время суток
' + + '