isle.pizza/debug.js
Christian Semmler 572219f703
Add debug menu
2026-01-01 09:34:47 -07:00

215 lines
7.2 KiB
JavaScript

(async function() {
const debugUI = document.getElementById('debug-ui');
const canvas = document.getElementById('canvas');
// Fetch and inject debug panel HTML
try {
const response = await fetch('debug.html');
const html = await response.text();
debugUI.innerHTML = html;
} catch (error) {
console.error('Failed to load debug panel:', error);
return;
}
// Now get references to elements after they've been injected
const debugToggle = document.getElementById('debug-toggle');
const debugPanel = document.getElementById('debug-panel');
const debugPasswordBtn = document.querySelector('.debug-password');
const requiresDebugBtns = document.querySelectorAll('.requires-debug');
let debugModeActive = false;
// Key code mapping for special keys
const keyCodeMap = {
'Pause': { key: 'Pause', code: 'Pause', keyCode: 19 },
'Escape': { key: 'Escape', code: 'Escape', keyCode: 27 },
' ': { key: ' ', code: 'Space', keyCode: 32 },
'Tab': { key: 'Tab', code: 'Tab', keyCode: 9 },
'F11': { key: 'F11', code: 'F11', keyCode: 122 },
'F12': { key: 'F12', code: 'F12', keyCode: 123 },
'+': { key: '+', code: 'NumpadAdd', keyCode: 107 },
'-kp': { key: '-', code: 'NumpadSubtract', keyCode: 109 },
'*': { key: '*', code: 'NumpadMultiply', keyCode: 106 },
'/': { key: '/', code: 'NumpadDivide', keyCode: 111 },
// Digit keys
'0': { key: '0', code: 'Digit0', keyCode: 48 },
'1': { key: '1', code: 'Digit1', keyCode: 49 },
'2': { key: '2', code: 'Digit2', keyCode: 50 },
'3': { key: '3', code: 'Digit3', keyCode: 51 },
'4': { key: '4', code: 'Digit4', keyCode: 52 },
'5': { key: '5', code: 'Digit5', keyCode: 53 },
'6': { key: '6', code: 'Digit6', keyCode: 54 },
'7': { key: '7', code: 'Digit7', keyCode: 55 },
'8': { key: '8', code: 'Digit8', keyCode: 56 },
'9': { key: '9', code: 'Digit9', keyCode: 57 },
};
// Toggle debug panel
debugToggle.addEventListener('click', function(e) {
e.stopPropagation();
debugPanel.classList.toggle('open');
debugToggle.classList.toggle('active');
});
// Dispatch a keyboard event to the canvas
function sendKey(key) {
let keyInfo = keyCodeMap[key];
if (!keyInfo) {
// Regular character key (letters)
const char = key.toLowerCase();
const charCode = char.charCodeAt(0);
keyInfo = {
key: char,
code: 'Key' + char.toUpperCase(),
keyCode: charCode >= 97 && charCode <= 122 ? charCode - 32 : charCode
};
}
const eventInit = {
key: keyInfo.key,
code: keyInfo.code,
keyCode: keyInfo.keyCode,
which: keyInfo.keyCode,
bubbles: true,
cancelable: true
};
canvas.dispatchEvent(new KeyboardEvent('keydown', eventInit));
canvas.dispatchEvent(new KeyboardEvent('keyup', eventInit));
}
// Send a sequence of keys with delay (longer delay for multi-stage commands)
function sendKeySequence(keys, delay = 100) {
let index = 0;
function sendNext() {
if (index < keys.length) {
sendKey(keys[index]);
index++;
setTimeout(sendNext, delay);
} else {
canvas.focus();
}
}
sendNext();
}
// Update button states based on debug mode
function updateDebugModeUI() {
if (debugModeActive) {
debugPasswordBtn.classList.add('active');
debugPasswordBtn.textContent = 'Debug Mode Active';
requiresDebugBtns.forEach(btn => btn.classList.add('enabled'));
} else {
debugPasswordBtn.classList.remove('active');
debugPasswordBtn.textContent = 'Enter Debug Mode';
requiresDebugBtns.forEach(btn => btn.classList.remove('enabled'));
}
}
// Handle button clicks
debugPanel.addEventListener('click', function(e) {
const btn = e.target.closest('button');
if (!btn || btn === debugToggle) return;
const keys = btn.dataset.keys;
if (!keys) return;
e.preventDefault();
e.stopPropagation();
// Handle special cases
if (keys === 'ogel') {
// Enter debug password
sendKeySequence(['o', 'g', 'e', 'l']);
debugModeActive = true;
updateDebugModeUI();
return;
}
// For requires-debug buttons, ensure debug mode is active
if (btn.classList.contains('requires-debug') && !debugModeActive) {
// Auto-enter debug mode first
sendKeySequence(['o', 'g', 'e', 'l']);
debugModeActive = true;
updateDebugModeUI();
// Then send the actual keys after a delay
setTimeout(() => {
sendKeySequence(keys.split(''));
}, 500);
return;
}
// Handle multi-key sequences (like 'g1' for act switch or 'c00' for locations)
if (keys.length > 1 && !keyCodeMap[keys]) {
sendKeySequence(keys.split(''));
} else {
sendKey(keys);
canvas.focus();
}
});
// Handle location teleport
const locationSelect = document.getElementById('debug-location-select');
const gotoLocationBtn = document.getElementById('debug-goto-location');
gotoLocationBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
const locationValue = locationSelect.value;
if (!locationValue) return;
// Ensure debug mode is active
if (!debugModeActive) {
sendKeySequence(['o', 'g', 'e', 'l']);
debugModeActive = true;
updateDebugModeUI();
// Then send location keys after a delay
setTimeout(() => {
sendKeySequence(locationValue.split(''));
}, 500);
return;
}
sendKeySequence(locationValue.split(''));
});
// Handle animation playback
const animationSelect = document.getElementById('debug-animation-select');
const playAnimationBtn = document.getElementById('debug-play-animation');
playAnimationBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
const animationId = animationSelect.value;
if (!animationId) return;
// Ensure debug mode is active
if (!debugModeActive) {
sendKeySequence(['o', 'g', 'e', 'l']);
debugModeActive = true;
updateDebugModeUI();
// Then send animation keys after a delay
setTimeout(() => {
playAnimation(animationId);
}, 500);
return;
}
playAnimation(animationId);
});
function playAnimation(animationId) {
// Animation command: 'v' + 3 digits (padded with leading zeros)
const paddedId = animationId.toString().padStart(3, '0');
const keys = ['v', ...paddedId.split('')];
sendKeySequence(keys);
}
// Initialize UI
updateDebugModeUI();
})();