// Game data - legacy fallback and configuration const gameData = { // Main tasks - now sourced from mainGameData.js via GameDataManager mainTasks: [], // Consequence tasks - now sourced from mainGameData.js via GameDataManager consequenceTasks: [], // Image configuration supportedImageFormats: ['.jpg', '.jpeg', '.png', '.gif'], discoveredTaskImages: [], // Will be populated automatically discoveredConsequenceImages: [], // Will be populated automatically // Placeholder images for tasks that don't have specific images defaultImage: "images/placeholder.jpg", // Flash Message System - Training focused messages defaultFlashMessages: [ // Motivational messages { id: 1, text: "Good goon! Keep stroking and watching!", category: "motivational", enabled: true }, { id: 2, text: "Every edge makes you more submissive!", category: "motivational", enabled: true }, { id: 3, text: "Porn is your new reality!", category: "motivational", enabled: true }, { id: 4, text: "You're becoming such a good little gooner!", category: "motivational", enabled: true }, { id: 5, text: "Real men fuck while you watch!", category: "motivational", enabled: true }, // Encouraging messages { id: 6, text: "Your dedication to gooning is impressive!", category: "encouraging", enabled: true }, { id: 7, text: "Look how much porn you can handle now!", category: "encouraging", enabled: true }, { id: 8, text: "You're building incredible porn tolerance!", category: "encouraging", enabled: true }, { id: 9, text: "Accept your place as a beta watcher!", category: "encouraging", enabled: true }, { id: 10, text: "Your future is endless gooning sessions!", category: "encouraging", enabled: true }, // Achievement messages { id: 11, text: "Excellent edging performance!", category: "achievement", enabled: true }, { id: 12, text: "You're such a dedicated gooner!", category: "achievement", enabled: true }, { id: 13, text: "Another victory for porn addiction!", category: "achievement", enabled: true }, { id: 14, text: "Perfect submission!", category: "achievement", enabled: true }, { id: 15, text: "You're mastering the art of denial!", category: "achievement", enabled: true }, // Persistence messages { id: 16, text: "Don't stop gooning now - embrace it!", category: "persistence", enabled: true }, { id: 17, text: "Every stroke makes you weaker!", category: "persistence", enabled: true }, { id: 18, text: "Push deeper into submission!", category: "persistence", enabled: true }, { id: 19, text: "You belong on your knees watching!", category: "persistence", enabled: true }, { id: 20, text: "True submission is forged through endless edging!", category: "persistence", enabled: true } ], // Flash message configuration defaults defaultFlashConfig: { enabled: true, displayDuration: 3000, // 3 seconds intervalDelay: 45000, // 45 seconds position: 'center', animation: 'fade', fontSize: '24px', fontWeight: 'bold', color: '#ffffff', backgroundColor: 'rgba(0, 123, 255, 0.9)', borderRadius: '15px', padding: '20px 30px', maxWidth: '400px', zIndex: 10000 }, // Default Popup Image Configuration (Punishment System) defaultPopupImageConfig: { enabled: true, imageCount: 3, // Number of images to show imageCountMode: 'fixed', // 'fixed', 'random', 'range' minCount: 2, // For range mode maxCount: 10, // For range mode - increased from 5 displayDuration: 8000, // 8 seconds default durationMode: 'fixed', // 'fixed', 'random', 'range' minDuration: 5000, // For range mode (5s) maxDuration: 15000, // For range mode (15s) positioning: 'random', // 'random', 'cascade', 'grid', 'center' allowOverlap: true, fadeAnimation: true, blurBackground: true, preventClose: true, // Users cannot close these showTimer: true, // Show countdown timer triggerOnSkip: true, // Trigger when tasks are skipped intensity: 'medium', // 'low', 'medium', 'high' - affects default values // Size constraints for dynamic sizing minWidth: 200, maxWidth: 500, minHeight: 150, maxHeight: 400, viewportWidthRatio: 0.35, // Max 35% of viewport width viewportHeightRatio: 0.4 // Max 40% of viewport height }, // Academy Campaign Progress (The Academy 30-level progression) academyProgress: { version: 1, currentLevel: 1, highestUnlockedLevel: 1, completedLevels: [], currentArc: 'Foundation', failedAttempts: {}, totalSessionTime: 0, lastPlayedLevel: null, lastPlayedDate: null, graduationCompleted: false, freeplayUnlocked: false, ascendedModeUnlocked: false, selectedPath: null, featuresUnlocked: [] } }; // Load saved data from localStorage first, then merge defaults if (!window.gameData) { console.log('🔧 gameData.js: Initializing window.gameData...'); // Try to load from localStorage try { const stored = localStorage.getItem('webGame-data'); if (stored) { window.gameData = JSON.parse(stored); console.log('💾 gameData.js: Loaded existing data from localStorage'); console.log('💾 gameData.js: Has academyProgress:', !!window.gameData.academyProgress); if (window.gameData.academyProgress) { console.log('💾 gameData.js: Academy level:', window.gameData.academyProgress.currentLevel); } // Deep merge: Add missing default properties (for backwards compatibility) let mergedCount = 0; for (let key in gameData) { if (!(key in window.gameData)) { // Top-level property missing, add it window.gameData[key] = gameData[key]; mergedCount++; console.log(`🔄 gameData.js: Added missing property: ${key}`); } else if (typeof gameData[key] === 'object' && !Array.isArray(gameData[key]) && gameData[key] !== null) { // For objects, merge missing nested properties for (let nestedKey in gameData[key]) { if (!(nestedKey in window.gameData[key])) { window.gameData[key][nestedKey] = gameData[key][nestedKey]; mergedCount++; } } } } if (mergedCount > 0) { console.log(`🔄 gameData.js: Merged ${mergedCount} missing default properties`); } else { console.log('✅ gameData.js: All properties present, no merge needed'); } } else { // No saved data, use defaults window.gameData = gameData; console.log('🆕 gameData.js: Using default gameData (no saved data)'); } } catch (e) { console.error('❌ gameData.js: Error loading data, using defaults:', e); window.gameData = gameData; } } else { console.log('â„šī¸ gameData.js: window.gameData already exists, preserving it'); }