(function () { 'use strict'; // ============================================================ // ELEMENTS // ============================================================ const $screen = $('#deathscreen'); const $icon = $('#death-icon'); const $statusText = $('#status-text'); const $timerBar = $('#timer-bar'); const $timerLabel = $('#timer-label'); const $timerValue = $('#timer-value'); const $timerContainer = $('#timer-container'); const $actionText = $('#action-text'); const $dispatch = $('#dispatch'); const $dispatchStreet = $('#dispatch-street'); const $dispatchTitle = $('#dispatch-title'); const $dispatchSound = document.getElementById('dispatch-sound'); // ============================================================ // STATE // ============================================================ let locale = {}; let maxTimer = 0; let currentState = ''; let dispatchTimeout = null; let giveUpEnabled = false; let emsCalledFlag = false; // ============================================================ // HELPERS // ============================================================ function formatTime(seconds) { if (seconds < 0) seconds = 0; const m = Math.floor(seconds / 60); const s = seconds % 60; return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s); } function getIconForState(state) { switch (state) { case 'UNCONSCIOUS': return 'fa-heartbeat'; case 'BLEEDING_OUT': return 'fa-heart-crack'; case 'DEAD': return 'fa-skull-crossbones'; // fallback default: return 'fa-heartbeat'; } } function getStatusClass(state) { switch (state) { case 'UNCONSCIOUS': return ''; case 'BLEEDING_OUT': return 'bleeding'; case 'DEAD': return 'dead'; default: return ''; } } function getStatusText(state) { switch (state) { case 'UNCONSCIOUS': return locale.unconscious || 'Bewusstlos'; case 'BLEEDING_OUT': return locale.bleedingOut || 'Verblutung'; case 'DEAD': return locale.dead || 'Verstorben'; default: return ''; } } // ============================================================ // UI UPDATES // ============================================================ function updateActionText() { $actionText.removeClass('respawn-ready ems-called'); if (emsCalledFlag && giveUpEnabled) { $actionText.html( '' + (locale.callingEMS || 'Rettungsdienst wird gerufen...') + '' + '
' + '' + (locale.giveUpAvailable || 'Drücke [E] zum Aufgeben') + '' ); } else if (emsCalledFlag) { $actionText.text(locale.callingEMS || 'Rettungsdienst wird gerufen...'); $actionText.addClass('ems-called'); } else if (giveUpEnabled) { $actionText.html( (locale.callEMS || 'Halte [G] um den Rettungsdienst zu rufen') + '
' + '' + (locale.giveUpAvailable || 'Drücke [E] zum Aufgeben') + '' ); } else { $actionText.text(locale.callEMS || 'Halte [G] um den Rettungsdienst zu rufen'); } } function applyState(state) { currentState = state; const cls = getStatusClass(state); // Icon $icon.find('i').attr('class', 'fas ' + getIconForState(state)); $icon.removeClass('bleeding dead').addClass(cls); // Status text $statusText.text(getStatusText(state)); $statusText.removeClass('bleeding dead').addClass(cls); // Timer bar $timerBar.removeClass('bleeding dead').addClass(cls); // Action text — Flags beibehalten beim State-Wechsel if (state === 'UNCONSCIOUS' || state === 'BLEEDING_OUT') { updateActionText(); } // Timer container wieder einblenden if (state === 'UNCONSCIOUS' || state === 'BLEEDING_OUT') { $timerContainer.show(); } // Timer label $timerLabel.text(locale.timerLabel || 'Verblutung in'); } function updateTimer(seconds) { $timerValue.text(formatTime(seconds)); if (maxTimer > 0) { const percent = (seconds / maxTimer) * 100; $timerBar.css('width', percent + '%'); } } // ============================================================ // ACTIONS // ============================================================ function showDeathscreen(data) { locale = data.locale || {}; maxTimer = data.timer || 0; giveUpEnabled = false; emsCalledFlag = false; applyState(data.state); updateTimer(data.timer); $screen.removeClass('hidden'); // Trigger reflow, dann visible setzen für Transition void $screen[0].offsetWidth; $screen.addClass('visible'); } function hideDeathscreen() { $screen.removeClass('visible'); setTimeout(function () { $screen.addClass('hidden'); currentState = ''; }, 800); } // ============================================================ // NUI MESSAGE HANDLER // ============================================================ window.addEventListener('message', function (event) { var data = event.data; switch (data.action) { case 'show': showDeathscreen(data); break; case 'update': if (data.state !== currentState) { maxTimer = data.timer; applyState(data.state); } updateTimer(data.timer); break; case 'emsCalled': emsCalledFlag = true; updateActionText(); break; case 'enableGiveUp': giveUpEnabled = true; updateActionText(); break; case 'showDispatch': $dispatchTitle.text(data.title || 'Notruf'); $dispatchStreet.text(data.street || 'Unbekannter Standort'); $dispatch.removeClass('hidden'); if ($dispatchSound) { $dispatchSound.currentTime = 0; $dispatchSound.volume = 0.5; $dispatchSound.play().catch(function () {}); } if (dispatchTimeout) clearTimeout(dispatchTimeout); dispatchTimeout = setTimeout(function () { $dispatch.addClass('hidden'); }, 15000); break; case 'hideDispatch': $dispatch.addClass('hidden'); if (dispatchTimeout) clearTimeout(dispatchTimeout); break; case 'hide': hideDeathscreen(); break; } }); })();