206 lines
7.8 KiB
JavaScript
Executable File
206 lines
7.8 KiB
JavaScript
Executable File
// Magisches Runen-Drehschloss (Cryptex Engine - Mobile First)
|
|
(function() {
|
|
const DIALS = [
|
|
// Dial 0: Houses
|
|
[
|
|
{ icon: '🦁', name: 'Löwe' },
|
|
{ icon: '🐍', name: 'Schlange' },
|
|
{ icon: '🦅', name: 'Rabe' },
|
|
{ icon: '🦡', name: 'Dachs' }
|
|
],
|
|
// Dial 1: Astral
|
|
[
|
|
{ icon: '☀️', name: 'Sonne' },
|
|
{ icon: '🌙', name: 'Mond' },
|
|
{ icon: '⭐', name: 'Stern' },
|
|
{ icon: '⚡', name: 'Blitz' }
|
|
],
|
|
// Dial 2: Elements
|
|
[
|
|
{ icon: '🔥', name: 'Feuer' },
|
|
{ icon: '💧', name: 'Wasser' },
|
|
{ icon: '🌿', name: 'Kräuter' },
|
|
{ icon: '💨', name: 'Wind' }
|
|
],
|
|
// Dial 3: Artifacts
|
|
[
|
|
{ icon: '🗝️', name: 'Schlüssel' },
|
|
{ icon: '🪄', name: 'Zauberstab' },
|
|
{ icon: '📜', name: 'Rolle' },
|
|
{ icon: '⚗️', name: 'Phiole' }
|
|
]
|
|
];
|
|
|
|
// Initial indices (unsolved)
|
|
const state = [0, 0, 1, 0];
|
|
let isUnlocked = false;
|
|
|
|
// Elements
|
|
const feedbackBox = document.getElementById('cryptexFeedback');
|
|
const successPanel = document.getElementById('cryptexSuccess');
|
|
const unlockBtn = document.getElementById('unlockCryptexBtn');
|
|
|
|
window.stepDial = function(dialIdx, dir) {
|
|
if (isUnlocked) return;
|
|
|
|
const dial = DIALS[dialIdx];
|
|
state[dialIdx] = (state[dialIdx] + dir + dial.length) % dial.length;
|
|
|
|
const symEl = document.getElementById(`sym${dialIdx}`);
|
|
const lblEl = document.getElementById(`lbl${dialIdx}`);
|
|
|
|
if (window.navigator && window.navigator.vibrate) window.navigator.vibrate(20);
|
|
if (window.soundFX) window.soundFX.playStoneSlide();
|
|
|
|
// Quick flip animation
|
|
symEl.style.transform = dir > 0 ? 'translateY(12px) scale(0.85)' : 'translateY(-12px) scale(0.85)';
|
|
symEl.style.opacity = '0.4';
|
|
|
|
setTimeout(() => {
|
|
const currentItem = dial[state[dialIdx]];
|
|
symEl.innerText = currentItem.icon;
|
|
lblEl.innerText = currentItem.name;
|
|
symEl.style.transform = 'translateY(0) scale(1)';
|
|
symEl.style.opacity = '1';
|
|
}, 80);
|
|
};
|
|
|
|
// Mobile Swipe Handler for each cylinder
|
|
for (let i = 0; i < 4; i++) {
|
|
const cyl = document.getElementById(`cylinder${i}`);
|
|
if (!cyl) continue;
|
|
|
|
let startY = 0;
|
|
let isTouching = false;
|
|
|
|
cyl.addEventListener('touchstart', (e) => {
|
|
if (e.touches.length > 0) {
|
|
startY = e.touches[0].clientY;
|
|
isTouching = true;
|
|
}
|
|
}, { passive: true });
|
|
|
|
cyl.addEventListener('touchend', (e) => {
|
|
if (!isTouching) return;
|
|
isTouching = false;
|
|
const endY = e.changedTouches[0].clientY;
|
|
const diff = endY - startY;
|
|
|
|
// If swiped more than 20px
|
|
if (Math.abs(diff) > 20) {
|
|
e.preventDefault();
|
|
if (diff < 0) {
|
|
window.stepDial(i, 1); // Swipe Up -> Next
|
|
} else {
|
|
window.stepDial(i, -1); // Swipe Down -> Prev
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
window.checkCryptex = async function() {
|
|
if (isUnlocked) return;
|
|
|
|
const currentCombination = [
|
|
DIALS[0][state[0]].icon,
|
|
DIALS[1][state[1]].icon,
|
|
DIALS[2][state[2]].icon,
|
|
DIALS[3][state[3]].icon
|
|
];
|
|
|
|
try {
|
|
const res = await fetch('/api/cryptex/unlock', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ combination: currentCombination })
|
|
});
|
|
const data = await res.json();
|
|
|
|
if (data.success) {
|
|
isUnlocked = true;
|
|
if (unlockBtn) unlockBtn.style.display = 'none';
|
|
|
|
if (window.soundFX) {
|
|
window.soundFX.playKeyChime();
|
|
window.soundFX.playMagicSuccess();
|
|
}
|
|
if (window.navigator && window.navigator.vibrate) {
|
|
window.navigator.vibrate([60, 100, 150]);
|
|
}
|
|
|
|
// Show golden shine on cylinders
|
|
document.querySelectorAll('.dial-cylinder').forEach(c => {
|
|
c.style.borderColor = 'var(--gold)';
|
|
c.style.boxShadow = '0 0 20px var(--gold)';
|
|
});
|
|
|
|
if (feedbackBox) {
|
|
feedbackBox.style.display = 'block';
|
|
feedbackBox.style.background = 'rgba(46, 204, 113, 0.25)';
|
|
feedbackBox.style.border = '1px solid #2ecc71';
|
|
feedbackBox.style.color = '#2ecc71';
|
|
feedbackBox.innerText = data.message;
|
|
}
|
|
|
|
if (data.new_item && window.notifyNewItem) {
|
|
window.notifyNewItem(data.new_item);
|
|
}
|
|
|
|
if (successPanel) successPanel.style.display = 'block';
|
|
|
|
if (window.showChamberVictory) {
|
|
window.showChamberVictory({
|
|
chamberBadge: "Kammer IV: Das Runen-Drehschloss",
|
|
title: "🔐 Gründer-Siegel Entriegelt!",
|
|
statsHtml: `<span>🦁 Löwe</span><span>🌙 Mond</span><span>🔥 Feuer</span><span>🪄 Zauberstab</span>`,
|
|
item: data.new_item || {
|
|
id: "cryptex_key",
|
|
name: "Schlüssel der Gründer",
|
|
icon: "🗝️",
|
|
desc: "Ein uralter Messingschlüssel. Er sperrt die Pforte zur Verteidigungs-Kammer auf!"
|
|
},
|
|
storyText: "Mit einem satten Grollen rasten die vier massiven Messingbolzen ein! Das Tor schnappt auf. Der <strong>Schlüssel der Gründer</strong> und <strong>Snapes Logik-Rolle</strong> wandern in deinen Beutel. Dahinter hörst du lautes Geschrei: <strong>Wichtel-Panik</strong>!",
|
|
nextUrl: "/pixies",
|
|
nextBtnText: "➔ Weiter zu Kammer V: Wichtel-Panik 🧚"
|
|
});
|
|
}
|
|
|
|
} else {
|
|
if (window.soundFX) window.soundFX.playWhoosh();
|
|
if (window.navigator && window.navigator.vibrate) {
|
|
window.navigator.vibrate([40, 40]);
|
|
}
|
|
|
|
const box = document.querySelector('.cryptex-box');
|
|
box.style.transform = 'translateX(-8px)';
|
|
setTimeout(() => box.style.transform = 'translateX(8px)', 80);
|
|
setTimeout(() => box.style.transform = 'translateX(-4px)', 160);
|
|
setTimeout(() => box.style.transform = 'translateX(0)', 240);
|
|
|
|
if (feedbackBox) {
|
|
feedbackBox.style.display = 'block';
|
|
feedbackBox.style.background = 'rgba(231, 76, 60, 0.25)';
|
|
feedbackBox.style.border = '1px solid #e74c3c';
|
|
feedbackBox.style.color = '#e74c3c';
|
|
feedbackBox.innerText = data.message;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error("Cryptex check error:", e);
|
|
}
|
|
};
|
|
|
|
// Felix Felicis Lucky Intuition Action
|
|
window.useFelixFelicisHint = function() {
|
|
if (window.soundFX) window.soundFX.playMagicSuccess();
|
|
if (window.showFloatingToast) {
|
|
window.showFloatingToast("🍀 <strong>Felix Felicis wirkt!</strong> Eine goldene Stimme flüstert: <em>»Löwe 🦁 und Mond 🌙 weisen den Weg!«</em>");
|
|
}
|
|
// Guide dials 0 and 1
|
|
dials[0] = 0; // 🦁
|
|
dials[1] = 1; // 🌙
|
|
updateDialDisplay(0);
|
|
updateDialDisplay(1);
|
|
};
|
|
})();
|