// References to main UI elements
const titleOverlay = document.getElementById('title-overlay');
const splashImageDiv = document.getElementById('splash-image');
const mainMenu = document.getElementById('main-menu');
const joinButton = document.getElementById('join-button'); // This is the "Games"
button
const gameUi = document.getElementById('game-ui');
const exitButton = document.getElementById('exit-button');
// References to menu containers and their toggle buttons
const titleSettingsButton = document.getElementById('title-settings-button');
const settingsContainer = document.getElementById('settings-container');
const settingsBackButton = settingsContainer ?
settingsContainer.querySelector('.back-button') : null;
const titleAvatarButton = document.getElementById('title-avatar-button');
const avatarContainer = document.getElementById('avatar-container');
const avatarBackButton = avatarContainer ? avatarContainer.querySelector('.back-
button') : null;
// NEW: References for the Games Menu
const gamesMenuContainer = document.getElementById('games-menu-container');
const gamesMenuBackButton = gamesMenuContainer ?
gamesMenuContainer.querySelector('.back-button') : null;
// NEW: Add references for Studio menu (ID set in index.html)
const studioMenuContainer = document.getElementById('studio-menu-container');
const studioMenuBackButton = studioMenuContainer ?
studioMenuContainer.querySelector('.back-button') : null;
// New references for the Admin Panel
const adminButton = document.getElementById('admin-button');
const adminPanelContainer = document.getElementById('admin-panel-container');
const adminPanelBackButton = adminPanelContainer ?
adminPanelContainer.querySelector('.back-button') : null;
// New reference for the Clear Chat Button
const clearChatButton = document.getElementById('clear-chat-button');
// NEW: References for the Jumpscare Player input and button
const jumpscareUsernameInput = adminPanelContainer ?
adminPanelContainer.querySelector('#jumpscare-username-input') : null;
const jumpscareFileInput = adminPanelContainer ?
adminPanelContainer.querySelector('#jumpscare-file-input') : null;
const jumpscarePlayerButton = adminPanelContainer ?
adminPanelContainer.querySelector('#jumpscare-player-button') : null;
const jumpscareStatus = adminPanelContainer ?
adminPanelContainer.querySelector('#jumpscare-status') : null;
const jumpscareOverlay = document.getElementById('jumpscare-overlay');
const jumpscareImage = document.getElementById('jumpscare-image');
// NEW: References for Warmmoonbeam Exclusive T-shirt Button and Status
const equipWarmmoonbeamTshirtButton = adminPanelContainer ?
adminPanelContainer.querySelector('#equip-warmmoonbeam-tshirt-button') : null;
const warmmoonbeamTshirtStatus = adminPanelContainer ?
adminPanelContainer.querySelector('#warmmoonbeam-tshirt-status') : null;
// NEW: References for Build Mode Button and Status (Admin Panel)
const toggleBuildModeButton = adminPanelContainer ?
adminPanelContainer.querySelector('#toggle-build-mode-button') : null;
const buildModeStatus = adminPanelContainer ?
adminPanelContainer.querySelector('#build-mode-status') : null;
// NEW: Reference for the In-Game Build Mode Button
const ingameBuildModeButton = document.getElementById('ingame-build-mode-button');
// NEW: References for Save/Load Build to File buttons
const saveBuildToFileButton = document.getElementById('save-build-to-file-button');
const loadBuildFromFileButton = document.getElementById('load-build-from-file-
button');
const loadBuildFileInput = document.getElementById('load-build-file-input');
const buildSaveStatus = document.getElementById('build-save-status');
// NEW: References for the Emotes button and options container
const emotesButton = document.getElementById('emotes-button');
const emoteOptionsContainer = document.getElementById('emote-options');
const emoteOptionButtons = emoteOptionsContainer ?
emoteOptionsContainer.querySelectorAll('.emote-option-button') : [];
// Reference for Show Hitboxes checkbox
const showHitboxesCheckbox = adminPanelContainer ?
adminPanelContainer.querySelector('#show-hitboxes-checkbox') : null;
// Import the clearChat function from chat.js
import { clearChatMessages } from './chat.js';
// Import ADMIN_USERS, SPECIAL_USER_WARMMOONBEAM and OWNER_USER from
playerManager.js
import { ADMIN_USERS, SPECIAL_USER_WARMMOONBEAM, OWNER_USER } from
'./playerManager.js';
// Import displayPlayerEmote from playerManager.js
import { displayPlayerEmote as displayPlayerEmoteLogic } from './playerManager.js';
// Import playScreamSound from audio.js
import { playScreamSound } from './audio.js';
// Import toggleBuildMode and showBlockHitboxes from gameLogic.js
// NEW: Import saveBuildToFile, loadBuildFromFile
import { toggleBuildMode, showBlockHitboxes, saveBuildToFile, loadBuildFromFile }
from './gameLogic.js';
// Import the room object to access WebsimSocket instance
import { room } from './websim.js';
// Import settings to check build mode state
import { settings } from './settings.js';
// Local Storage Key for splash screen seen status
const SPLASH_SEEN_STORAGE_KEY = 'hasSeenSplash';
// Function to check if the user has seen the splash screen before
function hasSeenSplash() {
try {
return localStorage.getItem(SPLASH_SEEN_STORAGE_KEY) === 'true';
} catch (error) {
console.error("Error accessing local storage for splash status:", error);
return false;
}
}
// Function to mark the splash screen as seen
function setSeenSplash() {
try {
localStorage.setItem(SPLASH_SEEN_STORAGE_KEY, 'true');
} catch (error) {
console.error("Error setting local storage for splash status:", error);
}
}
// Helper function to hide only the splash image div
function hideSplash() {
if (splashImageDiv) {
splashImageDiv.style.display = 'none';
splashImageDiv.removeEventListener('click', handleSplashClick);
}
}
// Helper function to hide all sub-menus and show main menu
function hideAllMenus() {
if (settingsContainer) settingsContainer.style.display = 'none';
if (avatarContainer) avatarContainer.style.display = 'none';
if (gamesMenuContainer) gamesMenuContainer.style.display = 'none';
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
if (mainMenu) mainMenu.style.display = 'block';
console.log("UI Manager: Hid title sub-menus and showing main menu.");
}
// Function to hide the admin panel
function hideAdminPanel() {
if (adminPanelContainer) adminPanelContainer.style.display = 'none';
console.log("UI Manager: Hid admin panel.");
}
// Handler for splash image click
function handleSplashClick() {
console.log("UI Manager: Splash image clicked, transitioning to Main Menu.");
hideSplash();
hideAllMenus();
setSeenSplash();
}
// Function to show the main title screen
function showTitleScreen() {
console.log("UI Manager: Showing Title Screen.");
if (gameUi) gameUi.style.display = 'none';
hideAdminPanel();
hideEmoteOptions();
if (room && room.updatePresence) {
console.log("UI Manager: Updating presence - setting gameId to null.");
room.updatePresence({ gameId: null });
} else {
console.warn("UI Manager: Websim room or updatePresence not available,
cannot update presence on exiting game.");
}
if (titleOverlay) {
titleOverlay.style.opacity = '1';
titleOverlay.style.display = 'flex';
}
if (!hasSeenSplash()) {
console.log("UI Manager: First load - showing splash screen.");
if (splashImageDiv) {
splashImageDiv.style.display = 'flex';
if (mainMenu) mainMenu.style.display = 'none';
if (settingsContainer) settingsContainer.style.display = 'none';
if (avatarContainer) avatarContainer.style.display = 'none';
if (gamesMenuContainer) gamesMenuContainer.style.display = 'none';
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
splashImageDiv.addEventListener('click', handleSplashClick);
} else {
console.warn("UI Manager: Splash image div not found. Skipping splash
screen logic.");
hideAllMenus();
setSeenSplash();
}
} else {
console.log("UI Manager: Splash screen already seen, showing main menu
directly.");
hideSplash();
hideAllMenus();
}
}
// Function to show the game UI (hiding the title overlay)
function showGameUI(gameId = 'baseplate') {
console.log(`UI Manager: Showing Game UI for game ID: ${gameId}.`);
hideAdminPanel();
hideEmoteOptions();
hideSplash();
if (mainMenu) mainMenu.style.display = 'none';
if (settingsContainer) settingsContainer.style.display = 'none';
if (avatarContainer) avatarContainer.style.display = 'none';
if (gamesMenuContainer) gamesMenuContainer.style.display = 'none';
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
if (room && room.updatePresence) {
console.log(`UI Manager: Updating presence - setting gameId to $
{gameId}.`);
room.updatePresence({ gameId: gameId, position: { x: 0, y: 3, z: 0 } });
} else {
console.warn("UI Manager: Websim room or updatePresence not available,
cannot update presence on joining game.");
}
if (titleOverlay) {
titleOverlay.style.opacity = '0';
setTimeout(() => {
titleOverlay.style.display = 'none';
if (gameUi) gameUi.style.display = 'flex';
}, 500);
} else {
if (gameUi) gameUi.style.display = 'flex';
}
// Reset build save status message
if (buildSaveStatus) buildSaveStatus.textContent = '';
// Manage visibility of in-game build controls (Build Mode, Save, Load)
if (ingameBuildModeButton && saveBuildToFileButton && loadBuildFromFileButton)
{
ingameBuildModeButton.style.display = 'none';
saveBuildToFileButton.style.display = 'none';
loadBuildFromFileButton.style.display = 'none';
if (room && room.clientId && room.peers[room.clientId]) {
const currentUser = room.peers[room.clientId];
const games = room.collection('publicgame_v1').getList();
const currentGame = games.find(g => g.gameId === gameId);
if (currentUser && currentGame && currentGame.created_by ===
currentUser.username) {
ingameBuildModeButton.style.display = 'block';
ingameBuildModeButton.textContent = settings.buildModeActive ?
"Exit Build Mode" : "Enter Build Mode";
// Show Save/Load buttons only if build mode is active AND user
owns map
if (settings.buildModeActive) {
saveBuildToFileButton.style.display = 'block';
loadBuildFromFileButton.style.display = 'block';
}
}
}
}
}
// Function to show the Settings menu within the overlay
function showSettings() {
console.log("UI Manager: Showing Settings.");
hideSplash();
if (mainMenu) mainMenu.style.display = 'none';
if (avatarContainer) avatarContainer.style.display = 'none';
if (gamesMenuContainer) gamesMenuContainer.style.display = 'none';
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
if (settingsContainer) settingsContainer.style.display = 'flex';
}
// Function to show the Avatar menu within the overlay
function showAvatar() {
console.log("UI Manager: Showing Avatar.");
hideSplash();
if (mainMenu) mainMenu.style.display = 'none';
if (settingsContainer) settingsContainer.style.display = 'none';
if (gamesMenuContainer) gamesMenuContainer.style.display = 'none';
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
if (avatarContainer) avatarContainer.style.display = 'flex';
}
// NEW: Function to show the Games menu within the overlay
function showGamesMenu() {
console.log("UI Manager: Showing Games Menu.");
hideSplash();
if (mainMenu) mainMenu.style.display = 'none';
if (settingsContainer) settingsContainer.style.display = 'none';
if (avatarContainer) avatarContainer.style.display = 'none';
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
if (gamesMenuContainer) gamesMenuContainer.style.display = 'flex';
}
// NEW: Function to toggle the visibility of the emote options container
function toggleEmoteOptions() {
if (emoteOptionsContainer) {
const isVisible = emoteOptionsContainer.style.display === 'flex';
emoteOptionsContainer.style.display = isVisible ? 'none' : 'flex';
console.log("UI Manager: Emote options toggled:", !isVisible);
}
}
// NEW: Function to hide the emote options container
function hideEmoteOptions() {
if (emoteOptionsContainer) {
emoteOptionsContainer.style.display = 'none';
console.log("UI Manager: Emote options hidden.");
}
}
// Initialize all necessary UI event listeners
function initializeUIListeners() {
console.log("UI Manager: Initializing UI listeners.");
room.initialize().then(() => {
const localClient = room.peers[room.clientId];
if (localClient) {
const userInfoDiv = document.getElementById('user-info');
const userAvatarImg = document.getElementById('user-avatar');
const userNameSpan = document.getElementById('user-name');
if (userInfoDiv && userAvatarImg && userNameSpan) {
userAvatarImg.src = `https://images.websim.com/avatar/$
{localClient.username}`;
userNameSpan.textContent = localClient.username;
console.log(`Displayed user info for ${localClient.username}`);
const adminButton = document.getElementById('admin-button');
const adminPanelContainer = document.getElementById('admin-panel-
container');
const isAdmin = ADMIN_USERS.includes(localClient.username);
const isOwner = localClient.username === OWNER_USER;
if (isAdmin || isOwner) {
console.log(`User ${localClient.username} is an admin or owner.
Showing Admin Panel button.`);
if (adminButton) {
adminButton.style.display = 'block';
}
} else {
console.log(`User ${localClient.username} is not an admin or
owner.`);
if (adminButton) {
adminButton.style.display = 'none';
}
if (adminPanelContainer) {
adminPanelContainer.style.display = 'none';
console.log("UI Manager: Hid Admin Panel as user is not
admin or owner.");
}
}
} else {
console.warn("User info elements not found in DOM.");
}
} else {
console.warn("Websim local client info not available after
initialization.");
}
}).catch(err => console.error("Error initializing Websim room or loading user
info:", err));
if (joinButton) {
joinButton.addEventListener('click', showGamesMenu);
} else {
console.warn("UI Manager: Join button (Games) not found.");
}
if (exitButton) {
exitButton.addEventListener('click', showTitleScreen);
} else {
console.warn("UI Manager: Exit button not found.");
}
if (titleSettingsButton) {
titleSettingsButton.addEventListener('click', showSettings);
if (settingsBackButton) {
settingsBackButton.addEventListener('click', hideAllMenus);
} else {
console.warn("UI Manager: Settings back button not found.");
}
} else {
console.warn("UI Manager: Settings button not found.");
}
if (titleAvatarButton) {
titleAvatarButton.addEventListener('click', showAvatar);
if (avatarBackButton) {
avatarBackButton.addEventListener('click', hideAllMenus);
} else {
console.warn("UI Manager: Avatar back button not found.");
}
} else {
console.warn("UI Manager: Avatar button not found.");
}
if (gamesMenuContainer && gamesMenuBackButton) {
gamesMenuBackButton.addEventListener('click', hideAllMenus);
} else {
console.warn("UI Manager: Games Menu container or back button not found.");
}
const baseplateJoinBtn = document.getElementById('baseplate-join-btn');
if (baseplateJoinBtn) {
baseplateJoinBtn.addEventListener('click', (e) => {
const gameId = e.target.getAttribute('data-game-id');
console.log(`UI Manager: Baseplate Join button clicked for Game ID: $
{gameId}.`);
showGameUI(gameId);
});
} else {
console.warn("UI Manager: Baseplate Join button not found.");
}
const baseplateCard = document.getElementById('baseplate-card');
if (baseplateCard && baseplateJoinBtn) {
baseplateCard.addEventListener('click', (e) => {
if (e.target !== baseplateJoinBtn && !
baseplateJoinBtn.contains(e.target)) {
const gameId = baseplateCard.getAttribute('data-game-id');
console.log(`UI Manager: Baseplate Card clicked (not button) for
Game ID: ${gameId}.`);
showGameUI(gameId);
}
});
} else {
console.warn("UI Manager: Baseplate Card not found or Join button not
found, cannot add card click listener.");
}
const studioButton = document.getElementById('studio-button');
if (studioButton && studioMenuContainer) {
studioButton.addEventListener('click', () => {
if (mainMenu) mainMenu.style.display = 'none';
studioMenuContainer.style.display = 'flex';
});
}
if (studioMenuBackButton) {
studioMenuBackButton.addEventListener('click', () => {
if (studioMenuContainer) studioMenuContainer.style.display = 'none';
if (mainMenu) mainMenu.style.display = 'block';
});
}
if (adminButton) {
adminButton.addEventListener('click', () => {
console.log("Admin button clicked! Showing Admin Panel.");
if (adminPanelContainer) adminPanelContainer.style.display = 'flex';
hideEmoteOptions();
});
} else {
console.warn("UI Manager: Admin button not found.");
}
if (adminPanelBackButton) {
adminPanelBackButton.addEventListener('click', () => {
hideAdminPanel();
});
} else {
console.warn("UI Manager: Admin panel back button not found.");
}
if (clearChatButton) {
clearChatButton.addEventListener('click', clearChatMessages);
console.log("UI Manager: Added listener for Clear Chat Button.");
} else {
console.warn("UI Manager: Clear Chat Button not found.");
}
if (jumpscarePlayerButton && jumpscareUsernameInput && jumpscareFileInput &&
jumpscareStatus) {
jumpscarePlayerButton.addEventListener('click', async () => {
const usernameToJumpscare = jumpscareUsernameInput.value.trim();
const file = jumpscareFileInput.files[0];
if (!usernameToJumpscare) {
jumpscareStatus.textContent = 'Please enter a username to
jumpscare.';
jumpscareStatus.style.color = 'orange';
return;
}
if (!file) {
jumpscareStatus.textContent = 'Please select an image for the
jumpscare.';
jumpscareStatus.style.color = 'orange';
return;
}
if (!file.type.startsWith('image/')) {
jumpscareStatus.textContent = 'Invalid file type. Please select an
image.';
jumpscareStatus.style.color = 'orange';
jumpscareFileInput.value = '';
return;
}
jumpscareStatus.textContent = 'Uploading jumpscare image...';
jumpscareStatus.style.color = 'white';
jumpscarePlayerButton.disabled = true;
try {
const imageUrl = await window.websim.upload(file);
console.log('Jumpscare image uploaded:', imageUrl);
jumpscareStatus.textContent = 'Image uploaded! Sending
jumpscare...';
const targetPeer = Object.values(room.peers).find(peer =>
peer.username === usernameToJumpscare);
if (!targetPeer) {
jumpscareStatus.textContent = `User "${usernameToJumpscare}"
not found in room.`;
jumpscareStatus.style.color = 'red';
jumpscarePlayerButton.disabled = false;
return;
}
room.send({
type: 'jumpscare',
imageUrl: imageUrl,
targetUsername: usernameToJumpscare
});
jumpscareStatus.textContent = `Jumpscare sent to $
{usernameToJumpscare}!`;
jumpscareStatus.style.color = 'lightgreen';
console.log(`UI Manager: Jumpscare sent to ${usernameToJumpscare}
with image ${imageUrl}`);
} catch (error) {
console.error('Error uploading jumpscare image:', error);
jumpscareStatus.textContent = `Upload failed: ${error.message}`;
jumpscareStatus.style.color = 'red';
} finally {
jumpscarePlayerButton.disabled = false;
jumpscareFileInput.value = '';
}
});
console.log("UI Manager: Added listener for Jumpscare Player Button.");
} else {
console.warn("UI Manager: Jumpscare Player Button or related elements not
found.");
}
if (equipWarmmoonbeamTshirtButton) {
equipWarmmoonbeamTshirtButton.addEventListener('click', () => {
const localClient = room.peers[room.clientId];
if (!localClient || localClient.username !==
SPECIAL_USER_WARMMOONBEAM) {
if (warmmoonbeamTshirtStatus) {
warmmoonbeamTshirtStatus.textContent = `Error: Only $
{SPECIAL_USER_WARMMOONBEAM} can equip this.`;
warmmoonbeamTshirtStatus.style.color = 'red';
}
console.warn(`UI Manager: User ${localClient?.username} clicked
warmmoonbeam t-shirt button but is not ${SPECIAL_USER_WARMMOONBEAM}.`);
}
});
} else {
console.warn("UI Manager: Equip Warmmoonbeam T-Shirt Button not found.");
}
if (toggleBuildModeButton && buildModeStatus) {
toggleBuildModeButton.addEventListener('click', () => {
const result = toggleBuildMode();
buildModeStatus.textContent = result;
buildModeStatus.style.color = result.includes("enabled") ? 'lightgreen'
: 'orange';
if (ingameBuildModeButton && ingameBuildModeButton.style.display ===
'block') {
ingameBuildModeButton.textContent = result.includes("enabled") ?
"Exit Build Mode" : "Enter Build Mode";
}
console.log("UI Manager: Admin Panel Build Mode button clicked.");
});
console.log("UI Manager: Added listener for Admin Panel Build Mode
Button.");
} else {
console.warn("UI Manager: Admin Panel Build Mode Button or status element
not found.");
}
if (ingameBuildModeButton) {
ingameBuildModeButton.addEventListener('click', () => {
const result = toggleBuildMode();
ingameBuildModeButton.textContent = result.includes("enabled") ? "Exit
Build Mode" : "Enter Build Mode";
// Also update admin panel button if it exists
if (toggleBuildModeButton && buildModeStatus) {
buildModeStatus.textContent = result;
buildModeStatus.style.color = result.includes("enabled") ?
'lightgreen' : 'orange';
}
console.log("UI Manager: In-Game Build Mode button clicked.");
// Toggle visibility of Save/Load buttons based on new build mode state
// (and map ownership, which is implicitly handled by
ingameBuildModeButton visibility)
if (saveBuildToFileButton && loadBuildFromFileButton) {
if (result.includes("enabled")) {
saveBuildToFileButton.style.display = 'block';
loadBuildFromFileButton.style.display = 'block';
} else {
saveBuildToFileButton.style.display = 'none';
loadBuildFromFileButton.style.display = 'none';
if (buildSaveStatus) buildSaveStatus.textContent = ''; // Clear
status on exiting build mode
}
}
});
}
// NEW: Save Build to File Button Listener
if (saveBuildToFileButton) {
saveBuildToFileButton.addEventListener('click', () => {
if (settings.buildModeActive) { // Ensure build mode is active
saveBuildToFile();
} else {
if (buildSaveStatus) {
buildSaveStatus.textContent = "Enter Build Mode first!";
buildSaveStatus.style.color = "orange";
}
}
});
console.log("UI Manager: Added listener for Save Build to File button.");
} else {
console.warn("UI Manager: Save Build to File button not found.");
}
// NEW: Load Build from File Button Listener
if (loadBuildFromFileButton && loadBuildFileInput) {
loadBuildFromFileButton.addEventListener('click', () => {
if (settings.buildModeActive) { // Ensure build mode is active
loadBuildFileInput.click(); // Trigger hidden file input
} else {
if (buildSaveStatus) {
buildSaveStatus.textContent = "Enter Build Mode first!";
buildSaveStatus.style.color = "orange";
}
}
});
console.log("UI Manager: Added listener for Load Build from File button.");
loadBuildFileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
try {
loadBuildFromFile(e.target.result);
} catch (err) {
if (buildSaveStatus) {
buildSaveStatus.textContent = "Error processing file.";
buildSaveStatus.style.color = "red";
}
console.error("Error reading or processing build file:",
err);
}
};
reader.onerror = () => {
if (buildSaveStatus) {
buildSaveStatus.textContent = "Failed to read file.";
buildSaveStatus.style.color = "red";
}
console.error("Error reading file with FileReader.");
};
reader.readAsText(file);
}
// Reset file input to allow selecting the same file again
loadBuildFileInput.value = '';
});
console.log("UI Manager: Added listener for Load Build file input
change.");
} else {
console.warn("UI Manager: Load Build from File button or file input not
found.");
}
// Show Hitboxes Checkbox Listener
if (showHitboxesCheckbox) {
showHitboxesCheckbox.addEventListener('change', (e) => {
const show = !!showHitboxesCheckbox.checked;
showBlockHitboxes(show);
});
showBlockHitboxes(showHitboxesCheckbox.checked);
} else {
console.warn("UI Manager: Show Hitboxes Checkbox not found.");
}
if (emotesButton) {
emotesButton.addEventListener('click', toggleEmoteOptions);
console.log("UI Manager: Added listener for Emotes Button.");
} else {
console.warn("UI Manager: Emotes Button not found.");
}
if (emoteOptionsContainer) {
emoteOptionsContainer.addEventListener('click', (event) => {
const target = event.target;
if (target.classList.contains('emote-option-button')) {
const emoteType = target.getAttribute('data-emote');
console.log(`UI Manager: Emote option clicked: ${emoteType}`);
if (emoteType) {
if (room && room.send) {
const localClient = room.peers[room.clientId];
room.send({ type: 'emote', emoteType: emoteType, clientId:
room.clientId, username: localClient?.username });
console.log(`UI Manager: Sent emote event for type: $
{emoteType}`);
// Display emote locally for the player who clicked
if (localClient && localClient.id &&
playerCharacters[localClient.id]) {
displayPlayerEmoteLogic(localClient.id, emoteType);
}
} else {
console.warn("UI Manager: Websim room or send function not
available, cannot send emote event.");
}
hideEmoteOptions();
}
}
});
console.log("UI Manager: Added listener for Emote Option Buttons.");
} else {
console.warn("UI Manager: Emote Options Container not found.");
}
document.addEventListener('click', (event) => {
const target = event.target;
const isInsideEmoteUI = emotesButton && emotesButton.contains(target) ||
emoteOptionsContainer &&
emoteOptionsContainer.contains(target);
const isInsideChat = document.getElementById('chat-container') &&
document.getElementById('chat-container').contains(target);
if (emoteOptionsContainer && emoteOptionsContainer.style.display === 'flex'
&& !isInsideEmoteUI && !isInsideChat) {
hideEmoteOptions();
}
});
showTitleScreen();
}
function displayJumpscare(imageUrl) {
if (!jumpscareOverlay || !jumpscareImage) {
console.error("UI Manager: Jumpscare overlay or image element not found.");
return;
}
jumpscareImage.src = imageUrl;
jumpscareOverlay.style.display = 'flex';
playScreamSound();
setTimeout(() => {
jumpscareOverlay.style.display = 'none';
jumpscareImage.src = '';
}, 3000);
}
export {
initializeUIListeners,
showTitleScreen,
showGameUI,
showSettings,
showAvatar,
hideAllMenus,
hideAdminPanel,
displayJumpscare,
showGamesMenu
};