251 lines
10 KiB
JavaScript
Executable File
251 lines
10 KiB
JavaScript
Executable File
// Zaubertrank-Brauküche (Felix Felicis Potion Brewing Engine - SVG Overhaul)
|
|
(function() {
|
|
let currentStep = 1; // 1: Ingredients, 2: Stirring, 3: Heat, 4: Done
|
|
const ingredients = {
|
|
dragon: 0,
|
|
mandrake: 0,
|
|
star: 0
|
|
};
|
|
const targetIngredients = {
|
|
dragon: 2,
|
|
mandrake: 1,
|
|
star: 1
|
|
};
|
|
|
|
// DOM Elements
|
|
const stepBadge = document.getElementById('stepBadge');
|
|
const stepInstruction = document.getElementById('stepInstruction');
|
|
const stepSubtext = document.getElementById('stepSubtext');
|
|
const step1Wrapper = document.getElementById('step1Wrapper');
|
|
const totalIngredientsCount = document.getElementById('totalIngredientsCount');
|
|
|
|
// SVG Elements
|
|
const gradStop1 = document.getElementById('gradStop1');
|
|
const gradStop2 = document.getElementById('gradStop2');
|
|
const gradStop3 = document.getElementById('gradStop3');
|
|
const liquidSurface = document.getElementById('liquidSurface');
|
|
const stirSpoon = document.getElementById('stirSpoon');
|
|
const dropItemAnim = document.getElementById('dropItemAnim');
|
|
|
|
// Controls
|
|
const stirPanel = document.getElementById('stirPanel');
|
|
const stirCountSpan = document.getElementById('stirCount');
|
|
const stirBtn = document.getElementById('stirBtn');
|
|
const heatPanel = document.getElementById('heatPanel');
|
|
const tempIndicator = document.getElementById('tempIndicator');
|
|
const heatTimerSpan = document.getElementById('heatTimer');
|
|
const successPanel = document.getElementById('successPanel');
|
|
|
|
// Step 1: Add Ingredient
|
|
window.addIngredient = function(type) {
|
|
if (currentStep !== 1) return;
|
|
if (ingredients[type] >= targetIngredients[type]) return;
|
|
|
|
ingredients[type]++;
|
|
if (window.soundFX) window.soundFX.playBottleClink();
|
|
if (window.navigator && window.navigator.vibrate) window.navigator.vibrate(30);
|
|
|
|
// Update UI Badge
|
|
if (type === 'dragon') {
|
|
document.getElementById('countDragon').innerText = `${ingredients.dragon} / ${targetIngredients.dragon}`;
|
|
if (ingredients.dragon >= targetIngredients.dragon) document.getElementById('ingDragon').classList.add('done');
|
|
} else if (type === 'mandrake') {
|
|
document.getElementById('countMandrake').innerText = `${ingredients.mandrake} / ${targetIngredients.mandrake}`;
|
|
if (ingredients.mandrake >= targetIngredients.mandrake) document.getElementById('ingMandrake').classList.add('done');
|
|
} else if (type === 'star') {
|
|
document.getElementById('countStar').innerText = `${ingredients.star} / ${targetIngredients.star}`;
|
|
if (ingredients.star >= targetIngredients.star) document.getElementById('ingStar').classList.add('done');
|
|
}
|
|
|
|
const total = ingredients.dragon + ingredients.mandrake + ingredients.star;
|
|
if (totalIngredientsCount) totalIngredientsCount.innerText = total;
|
|
|
|
// Visual drop animation in SVG
|
|
if (dropItemAnim) {
|
|
const icons = { dragon: '🐉', mandrake: '🌿', star: '✨' };
|
|
dropItemAnim.textContent = icons[type];
|
|
dropItemAnim.style.display = 'block';
|
|
dropItemAnim.style.animation = 'ingredientDropAnim 0.5s ease-out forwards';
|
|
setTimeout(() => {
|
|
dropItemAnim.style.display = 'none';
|
|
}, 550);
|
|
}
|
|
|
|
// Ripple pulse on liquid
|
|
if (liquidSurface) {
|
|
liquidSurface.style.transform = 'scale(1.06)';
|
|
setTimeout(() => liquidSurface.style.transform = 'scale(1)', 200);
|
|
}
|
|
|
|
// Check if all ingredients added
|
|
if (total === 4) {
|
|
setTimeout(startStep2, 600);
|
|
}
|
|
};
|
|
|
|
// Step 2: Stirring
|
|
let completedStirs = 0;
|
|
|
|
function startStep2() {
|
|
currentStep = 2;
|
|
stepBadge.innerText = "Schritt 2: Gleichmäßig rühren";
|
|
stepInstruction.innerText = "Rühre den Kessel 3-mal um!";
|
|
stepSubtext.innerText = "Tippe auf den großen Rühr-Button, um die Essenzen zu vermengen.";
|
|
if (step1Wrapper) step1Wrapper.style.display = 'none';
|
|
if (stirPanel) stirPanel.style.display = 'flex';
|
|
|
|
// Show wooden spoon in cauldron
|
|
if (stirSpoon) stirSpoon.style.display = 'block';
|
|
|
|
// Shift liquid color to mystical purple
|
|
if (gradStop1 && gradStop2 && gradStop3) {
|
|
gradStop1.setAttribute('stop-color', '#9b59b6');
|
|
gradStop2.setAttribute('stop-color', '#8e44ad');
|
|
gradStop3.setAttribute('stop-color', '#341f47');
|
|
}
|
|
|
|
if (window.soundFX) window.soundFX.playStoneSlide();
|
|
}
|
|
|
|
window.doStir = function() {
|
|
if (currentStep !== 2) return;
|
|
completedStirs++;
|
|
if (stirCountSpan) stirCountSpan.innerText = completedStirs;
|
|
if (stirBtn) stirBtn.innerHTML = `🥄 Kessel umrühren! (<span>${completedStirs}</span> / 3)`;
|
|
|
|
if (window.soundFX) window.soundFX.playBottleClink();
|
|
if (window.navigator && window.navigator.vibrate) window.navigator.vibrate(35);
|
|
|
|
// Animate stirring spoon
|
|
if (stirSpoon) {
|
|
stirSpoon.classList.remove('stirring-active');
|
|
void stirSpoon.offsetWidth; // re-flow
|
|
stirSpoon.classList.add('stirring-active');
|
|
}
|
|
|
|
if (completedStirs >= 3) {
|
|
setTimeout(() => {
|
|
if (stirSpoon) stirSpoon.style.display = 'none';
|
|
if (stirPanel) stirPanel.style.display = 'none';
|
|
startStep3();
|
|
}, 600);
|
|
}
|
|
};
|
|
|
|
// Step 3: Heat Control
|
|
let currentTemp = 35; // percent (0-100)
|
|
let heatTimer = 0.0;
|
|
let heatInterval = null;
|
|
|
|
function startStep3() {
|
|
currentStep = 3;
|
|
stepBadge.innerText = "Schritt 3: Hitze balancieren";
|
|
stepInstruction.innerText = "Pumpe mit dem Blasebalg, um die Flammen zu nähren!";
|
|
stepSubtext.innerText = "Halte die Anzeige für 3 Sekunden im grünen Idealbereich (45% - 85%).";
|
|
if (heatPanel) heatPanel.classList.add('active');
|
|
|
|
// Shift liquid color to fiery orange
|
|
if (gradStop1 && gradStop2 && gradStop3) {
|
|
gradStop1.setAttribute('stop-color', '#e67e22');
|
|
gradStop2.setAttribute('stop-color', '#d35400');
|
|
gradStop3.setAttribute('stop-color', '#561d00');
|
|
}
|
|
|
|
if (window.soundFX) window.soundFX.playWhoosh();
|
|
|
|
heatInterval = setInterval(updateHeatLoop, 50);
|
|
}
|
|
|
|
window.pumpHeat = function() {
|
|
if (currentStep !== 3) return;
|
|
currentTemp = Math.min(100, currentTemp + 18);
|
|
if (window.soundFX) window.soundFX.playWhoosh();
|
|
if (window.navigator && window.navigator.vibrate) window.navigator.vibrate(20);
|
|
|
|
const bellows = document.getElementById('bellowsBtn');
|
|
if (bellows) {
|
|
bellows.style.transform = 'scale(0.92)';
|
|
setTimeout(() => bellows.style.transform = 'scale(1)', 100);
|
|
}
|
|
};
|
|
|
|
function updateHeatLoop() {
|
|
if (currentStep !== 3) return;
|
|
|
|
// Gentle cooling down
|
|
currentTemp = Math.max(0, currentTemp - 0.45);
|
|
if (tempIndicator) tempIndicator.style.width = currentTemp + '%';
|
|
|
|
// Check ideal zone (45% to 85%) - forgiving on mobile!
|
|
if (currentTemp >= 45 && currentTemp <= 85) {
|
|
heatTimer += 0.05;
|
|
if (heatTimerSpan) heatTimerSpan.innerText = heatTimer.toFixed(1);
|
|
if (tempIndicator) tempIndicator.style.background = '#2ecc71';
|
|
} else {
|
|
if (tempIndicator) tempIndicator.style.background = 'linear-gradient(90deg, #3498db, #f39c12, #e74c3c)';
|
|
}
|
|
|
|
if (heatTimer >= 3.0) {
|
|
clearInterval(heatInterval);
|
|
finishPotionBrew();
|
|
}
|
|
}
|
|
|
|
// Step 4: Victory
|
|
async function finishPotionBrew() {
|
|
currentStep = 4;
|
|
stepBadge.innerText = "✅ Trank vollendet!";
|
|
stepBadge.style.background = "rgba(46, 204, 113, 0.3)";
|
|
stepBadge.style.borderColor = "#2ecc71";
|
|
stepBadge.style.color = "#2ecc71";
|
|
|
|
stepInstruction.innerText = "Felix Felicis strahlt in reinem Gold!";
|
|
stepSubtext.innerText = "Dein Zaubertrank ist meisterhaft gelungen.";
|
|
|
|
if (heatPanel) heatPanel.classList.remove('active');
|
|
|
|
// Turn liquid into sparkling golden elixir
|
|
if (gradStop1 && gradStop2 && gradStop3) {
|
|
gradStop1.setAttribute('stop-color', '#fff6a5');
|
|
gradStop2.setAttribute('stop-color', '#ffd700');
|
|
gradStop3.setAttribute('stop-color', '#b7950b');
|
|
}
|
|
|
|
if (window.soundFX) window.soundFX.playMagicSuccess();
|
|
if (window.navigator && window.navigator.vibrate) window.navigator.vibrate([50, 100, 150]);
|
|
|
|
// API Completion Call
|
|
let newItem = null;
|
|
try {
|
|
const res = await fetch('/api/brew/complete', { method: 'POST' });
|
|
const data = await res.json();
|
|
if (data.new_item) newItem = data.new_item;
|
|
} catch (e) {
|
|
console.error("Brew complete error:", e);
|
|
}
|
|
|
|
if (!newItem) {
|
|
newItem = {
|
|
id: "felix_felicis",
|
|
name: "Felix Felicis",
|
|
icon: "🧪",
|
|
desc: "Ein Tropfen flüssiges Gold! Verleiht dir unerschütterliches Glück und enthüllt verborgene Runen."
|
|
};
|
|
}
|
|
|
|
if (successPanel) successPanel.style.display = 'block';
|
|
|
|
if (window.showChamberVictory) {
|
|
window.showChamberVictory({
|
|
chamberBadge: "Kammer III: Die Brauküche",
|
|
title: "⚗️ Zaubertrank Gemeistert!",
|
|
statsHtml: `<span>🧪 Elixier: <strong>Felix Felicis</strong></span><span>🌡️ Hitze: <strong>Perfekt gemeistert</strong></span>`,
|
|
item: newItem,
|
|
storyText: "Der Kessel erstrahlt in gleißendem, flüssigem Gold! Du füllst eine Phiole des unbezahlbaren <strong>Felix Felicis</strong> ab. Seine Wärme durchdringt deinen Geist. Mit geschärften Sinnen trittst du vor das gewaltige <strong>Runen-Drehschloss der vier Gründer</strong>!",
|
|
nextUrl: "/cryptex",
|
|
nextBtnText: "➔ Weiter zu Kammer IV: Das Drehschloss 🔐"
|
|
});
|
|
}
|
|
}
|
|
})();
|