import React, { useContext, useEffect, useState, useRef } from 'react'; import { motion, useMotionValue, useSpring } from 'framer-motion'; import { DndContext } from '../../context/DndContext'; import DndNavbar from './DndNavbar'; import DndFooter from './DndFooter'; import dndWallpapers from '../../utils/dndWallpapers'; import { parseWallpaperName } from '../../utils/dndUtils'; import '../../styles/dnd-refactor.css'; import { GameController, Flame, TreasureChest } from '@phosphor-icons/react'; import { useToast } from '../../hooks/useToast'; const Lightning = () =>
; const LootDiscovery = () => { const { addToast } = useToast(); const [showLoot, setShowLoot] = useState(false); const [lootPos, setLootPos] = useState({ top: '50%', left: '50%' }); useEffect(() => { const interval = setInterval(() => { // 50% chance every 15 seconds if (Math.random() > 0.5) { setLootPos({ top: `${30 + Math.random() * 40}%`, left: `${20 + Math.random() * 60}%`, }); setShowLoot(true); setTimeout(() => setShowLoot(false), 8000); // Hide after 8s } }, 15000); return () => clearInterval(interval); }, []); if (!showLoot) return null; return ( { const currentCount = parseInt( localStorage.getItem('fezcodex_loot_count') || '0', 10, ); const newCount = currentCount + 1; localStorage.setItem('fezcodex_loot_count', newCount.toString()); addToast({ title: 'Loot Discovered!', message: `You found an ancient relic in the archives. (Total Found: ${newCount})`, type: 'gold', }); setShowLoot(false); }} className="fixed z-[150] dnd-loot-item text-dnd-gold" style={{ top: lootPos.top, left: lootPos.left }} > ); }; const FireplaceAudio = () => { const [isPlaying, setIsPlaying] = useState(false); const audioRef = useRef(null); const toggleAudio = () => { if (isPlaying) { audioRef.current.pause(); } else { audioRef.current.play(); } setIsPlaying(!isPlaying); }; return (
); }; const FireOverlay = () =>
; const DustMotes = () => (
{[...Array(20)].map((_, i) => (
))}
); const FloatingRunes = () => { const runes = [ 'ᚠ', 'ᚢ', 'ᚦ', 'ᚨ', 'ᚱ', 'ᚲ', 'ᚷ', 'ᚹ', 'ᚺ', 'ᚾ', 'ᛁ', 'ᛃ', 'ᛈ', 'ᛇ', 'ᛉ', 'ᛊ', 'ᛏ', 'ᛒ', 'ᛖ', 'ᛗ', 'ᛚ', 'ᛜ', 'ᛞ', 'ᛟ', ]; return (
{[...Array(20)].map((_, i) => ( {runes[Math.floor(Math.random() * runes.length)]} ))}
); }; const ViewportFrame = () => ( <>
); const FireParticles = () => { const colors = [ 'radial-gradient(circle, #ff4500 0%, #ff8c00 70%, transparent 100%)', // Red-Orange 'radial-gradient(circle, #ff8c00 0%, #ffd700 70%, transparent 100%)', // Orange-Gold 'radial-gradient(circle, #ff0000 0%, #ff4500 70%, transparent 100%)', // Pure Red ]; return (
{[...Array(50)].map((_, i) => { const size = 3 + Math.random() * 8; return (
); })}
); }; const Torchlight = () => { const mouseX = useMotionValue(0); const mouseY = useMotionValue(0); const springX = useSpring(mouseX, { damping: 50, stiffness: 200 }); const springY = useSpring(mouseY, { damping: 50, stiffness: 200 }); useEffect(() => { const handleMouseMove = (e) => { mouseX.set(e.clientX); mouseY.set(e.clientY); }; window.addEventListener('mousemove', handleMouseMove); return () => window.removeEventListener('mousemove', handleMouseMove); }, [mouseX, mouseY]); return ( ); }; const DiceRoller = () => { const [roll, setRoll] = useState(null); const [isRolling, setIsRolling] = useState(false); const rollDice = () => { setIsRolling(true); setTimeout(() => { setRoll(Math.floor(Math.random() * 20) + 1); setIsRolling(false); }, 600); }; return (
{roll !== null && ( {roll === 20 ? 'CRITICAL SUCCESS!' : roll === 1 ? 'CRITICAL FAILURE...' : `YOU ROLLED: ${roll}`} )}
); }; const DndLayout = ({ children }) => { const { setBgImageName, isLightningEnabled, isLootDiscoveryEnabled, isFireOverlayEnabled, isFireParticlesEnabled, isViewportFrameEnabled, } = useContext(DndContext); const [bgImage, setBgImage] = useState(''); useEffect(() => { const randomImage = dndWallpapers[Math.floor(Math.random() * dndWallpapers.length)]; setBgImage(randomImage); setBgImageName(parseWallpaperName(randomImage.split('/').pop())); }, [setBgImageName]); return (
{isViewportFrameEnabled && } {isLightningEnabled && } {isLootDiscoveryEnabled && } {isFireOverlayEnabled && } {isFireParticlesEnabled && }
{/* Immersive Background */}
{/* Content Layer */}
{children}
{/* Global Vignette */}
); }; export default DndLayout;