Files
bootle/app/static/js/bottles.js
T

203 lines
9.6 KiB
JavaScript
Executable File

// Snape's 7 Potions Riddle & Interactive Bottle Board
(function() {
let selectedBottle = null;
const slots = document.querySelectorAll('.bottle-slot');
const selectedInfo = document.getElementById('selectedBottleInfo');
const btnDrinkAhead = document.getElementById('btnDrinkAhead');
const btnDrinkBack = document.getElementById('btnDrinkBack');
const modalBackdrop = document.getElementById('modalBackdrop');
const modalTitle = document.getElementById('modalTitle');
const modalText = document.getElementById('modalText');
const modalBtn = document.getElementById('modalBtn');
const modalIcon = document.getElementById('modalIcon');
// Bottle Descriptions based on Book Clues
const bottleDescriptions = {
1: "Eine dunkelbraune Phiole mittlerer Größe. Auf der linken Seite von Flasche 2.",
2: "Eine schlanke, grüne Glasflasche. Schmeckt laut Hinweis 4 exakt wie Flasche 6!",
3: "🔍 Die kleinste Flasche von allen (der 'Zwerg')! Sie enthält kaum mehr als einen einzigen Schluck.",
4: "Ein eigenartiger, kantiger Glaskolben mit trüber, unruhiger Flüssigkeit.",
5: "Eine bauchige Flasche aus Rauchglas. Steht direkt links von Flasche 6.",
6: "Eine elegante Flasche, die Zwillingsschwester von Flasche 2, auch wenn sie äußerlich verschieden wirken.",
7: "🏺 Die größte Flasche in der Reihe (der 'Riese')! Ein schwerer, bauchiger Dekanter."
};
slots.forEach(slot => {
slot.addEventListener('click', (e) => {
if (e.target.tagName === 'SELECT') return; // Don't trigger on tag dropdown
selectSlot(slot);
});
// Drag & Drop / Reordering support
slot.setAttribute('draggable', 'true');
slot.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', slot.dataset.index);
if (window.soundFX) window.soundFX.playStoneSlide();
});
slot.addEventListener('dragover', (e) => {
e.preventDefault();
slot.classList.add('drag-over');
});
slot.addEventListener('dragleave', () => {
slot.classList.remove('drag-over');
});
slot.addEventListener('drop', (e) => {
e.preventDefault();
slot.classList.remove('drag-over');
const sourceIndex = e.dataTransfer.getData('text/plain');
const sourceSlot = document.querySelector(`.bottle-slot[data-index="${sourceIndex}"]`);
if (sourceSlot && sourceSlot !== slot) {
swapSlots(sourceSlot, slot);
}
});
});
function swapSlots(slotA, slotB) {
if (window.soundFX) {
window.soundFX.playStoneSlide();
window.soundFX.playBottleClink();
}
// Swap inner contents except the pedestal number
const tempHTML = slotA.innerHTML;
slotA.innerHTML = slotB.innerHTML;
slotB.innerHTML = tempHTML;
// Restore event listeners on newly swapped selects
attachTagListeners();
selectSlot(slotB);
}
function selectSlot(slot) {
slots.forEach(s => s.classList.remove('selected'));
slot.classList.add('selected');
selectedBottle = parseInt(slot.dataset.index, 10);
if (window.soundFX) window.soundFX.playBottleClink();
if (btnDrinkAhead) btnDrinkAhead.disabled = false;
if (btnDrinkBack) btnDrinkBack.disabled = false;
if (selectedInfo) {
const desc = bottleDescriptions[selectedBottle] || "Eine geheimnisvolle Flasche.";
selectedInfo.innerHTML = `Gewählt: <strong>Flasche ${selectedBottle}</strong> — <em>${desc}</em>`;
}
}
function attachTagListeners() {
document.querySelectorAll('.bottle-tag-select').forEach(sel => {
sel.addEventListener('change', () => {
if (window.soundFX) window.soundFX.playStoneSlide();
});
});
}
attachTagListeners();
// Drink to pass Ahead (Black Fire)
if (btnDrinkAhead) {
btnDrinkAhead.addEventListener('click', () => {
if (!selectedBottle) return;
drinkBottle(selectedBottle, 'ahead');
});
}
// Drink to pass Back (Purple Fire)
if (btnDrinkBack) {
btnDrinkBack.addEventListener('click', () => {
if (!selectedBottle) return;
drinkBottle(selectedBottle, 'back');
});
}
async function drinkBottle(bottleIdx, gate) {
if (window.soundFX) window.soundFX.playBottleClink();
try {
const res = await fetch('/api/bottles/drink', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ bottle: bottleIdx, gate: gate, lang: 'de' })
});
const data = await res.json();
if (data.result === 'success_ahead') {
if (window.showChamberVictory) {
window.showChamberVictory({
chamberBadge: "Kammer VI: Snapes Flaschenrätsel",
title: "🔥 Schwarzes Feuer Durchquert!",
statsHtml: `<span>🧪 Flasche 3 (Zwerg): <strong>Schutztrank</strong></span><span>🔥 Schwarzes Feuer: <strong>Besiegt!</strong></span>`,
item: data.new_item || {
id: "philosophers_stone",
name: "Stein der Weisen",
icon: "💎",
desc: "Der legendäre rote Alchemistenstein!"
},
storyText: "Ein eisiger Frosthauch hüllt deinen Körper ein! Du schreitest durch das tosend schwarze Feuer, ohne auch nur ein Haar zu versengen. Dahinter enthüllt sich das größte Geheimnis von Hogwarts: <strong>Der Spiegel Nerhegeb und der Stein der Weisen</strong>!",
nextUrl: "/finale",
nextBtnText: "➔ Zum großen Finale: Der Stein der Weisen 💎"
});
} else {
if (window.soundFX) window.soundFX.playMagicSuccess();
if (window.notifyNewItem && data.new_item) {
window.notifyNewItem(data.new_item);
}
modalIcon.innerText = "❄️⚡";
modalTitle.innerText = "Hervorragend kombiniert!";
modalTitle.style.color = "#ffd700";
modalText.innerHTML = `Du hast die <strong>kleinste Flasche (Flasche 3, den 'Zwerg')</strong> getrunken!<br><br>
${data.message}<br><br>
Das schwarze Feuer teilt sich mit einem frostigen Zischen. Der Weg zum Stein der Weisen liegt frei vor dir!`;
modalBtn.innerText = "Zum Finale & Escape-Triumph 🏆";
modalBtn.onclick = () => { window.location.href = data.next_url; };
modalBackdrop.classList.add('show');
}
} else if (data.result === 'success_back') {
if (window.soundFX) window.soundFX.playMagicSuccess();
modalIcon.innerText = "🟣";
modalTitle.innerText = "Rückzug gesichert!";
modalText.innerHTML = `Du hast die <strong>größte Flasche (Flasche 7, den 'Riesen')</strong> getrunken.<br><br>
${data.message}<br><br>
Du kannst sicher durch die violetten Flammen zurückweichen, um deinen Gefährten zu helfen oder den Besenflug nochmals zu betreten.`;
modalBtn.innerText = "Zurück zum Besenflug 🧹";
modalBtn.onclick = () => { window.location.href = data.next_url; };
modalBackdrop.classList.add('show');
} else if (data.result === 'poison') {
if (window.soundFX) window.soundFX.playPoisonSizzle();
modalIcon.innerText = "💀";
modalTitle.innerText = "Tödliches Gift!";
modalTitle.style.color = "#e74c3c";
modalText.innerHTML = `${data.message}<br><br>
<strong>Snapes Rätsel-Hinweis:</strong><br>
<em>"So schlau sich das Gift auch zu tarnen mag,<br>
stets steht es zur Linken vom Wein im Gelag."</em>`;
modalBtn.innerText = "Erneut analysieren 📜";
modalBtn.onclick = () => { modalBackdrop.classList.remove('show'); };
modalBackdrop.classList.add('show');
} else if (data.result === 'wine') {
if (window.soundFX) window.soundFX.playPoisonSizzle();
modalIcon.innerText = "🍷";
modalTitle.innerText = "Harmloser Brennnesselwein";
modalTitle.style.color = "#e67e22";
modalText.innerHTML = `${data.message}<br><br>
Du spürst keinerlei Schutz vor der Hitze der Flammen. Wenn du jetzt hineintrittst, verbrennst du! Lies die Verse auf dem Pergament noch einmal gründlich.`;
modalBtn.innerText = "Verstanden 📜";
modalBtn.onclick = () => { modalBackdrop.classList.remove('show'); };
modalBackdrop.classList.add('show');
} else {
if (window.soundFX) window.soundFX.playPoisonSizzle();
modalIcon.innerText = "⚠️";
modalTitle.innerText = "Falsche Flamme!";
modalText.innerText = data.message;
modalBtn.innerText = "Zurück";
modalBtn.onclick = () => { modalBackdrop.classList.remove('show'); };
modalBackdrop.classList.add('show');
}
} catch (e) {
console.error(e);
}
}
})();