diff --git a/game_server.py b/game_server.py index 71f9583..d6f7687 100644 --- a/game_server.py +++ b/game_server.py @@ -373,20 +373,24 @@ def get_user_achievements(user_id): return jsonify({'error': 'User not found'}), 404 user_achievements = user.get('achievements', []) - achievement_details = list(achievements_collection.find({'id': {'$in': user_achievements}})) + all_achievements = list(achievements_collection.find()) - for achievement in achievement_details: + for achievement in all_achievements: achievement['_id'] = str(achievement['_id']) + achievement['unlocked'] = achievement['id'] in user_achievements - # Check for unlocked classes + # Check for unlockable classes unlocked_classes = list(classes_collection.find({'unlock_requirements.achievement': achievement['id']})) achievement['unlocked_classes'] = [{'name': c['name'], 'image': c['image_source']} for c in unlocked_classes] - # Check for unlocked skins + # Check for unlockable skins unlocked_skins = list(skins_collection.find({'unlock_requirements.achievement': achievement['id']})) achievement['unlocked_skins'] = [{'name': s['name'], 'image': s['image_source']} for s in unlocked_skins] + + if not achievement['unlocked']: + achievement['unlock_requirements'] = achievement.get('unlock_requirements', 'Requirements not specified') - return jsonify(achievement_details), 200 + return jsonify(all_achievements), 200 @app.route('/unlink-discord', methods=['POST']) diff --git a/static/js/game.js b/static/js/game.js index 795d59a..7c46c13 100644 --- a/static/js/game.js +++ b/static/js/game.js @@ -163,7 +163,7 @@ function fetchUserAchievements() { }) .then(achievements => { if (Array.isArray(achievements) && achievements.length > 0) { - displayUserAchievements(achievements); + displayAllAchievements(achievements); } else { displayNoAchievementsMessage(achievementsGrid); } @@ -200,8 +200,7 @@ function displayErrorMessage(container, message) { `; } - -function displayUserAchievements(achievements) { +function displayAllAchievements(achievements) { const achievementsGrid = document.getElementById('achievementsGrid'); if (!achievementsGrid) { console.error('Achievements grid not found'); @@ -212,7 +211,13 @@ function displayUserAchievements(achievements) { achievements.forEach(achievement => { const achievementElement = document.createElement('div'); achievementElement.classList.add('achievement'); - achievementElement.innerHTML = `${achievement.name}`; + if (!achievement.unlocked) { + achievementElement.classList.add('locked'); + } + achievementElement.innerHTML = ` + ${achievement.name} + ${!achievement.unlocked ? '
' : ''} + `; achievementElement.addEventListener('click', () => showAchievementInfo(achievement)); achievementElement.addEventListener('mouseover', () => showAchievementInfo(achievement)); achievementsGrid.appendChild(achievementElement); @@ -224,6 +229,7 @@ function displayUserAchievements(achievements) { } } + function showAchievementInfo(achievement) { const image = document.getElementById('achievementImage'); const name = document.getElementById('achievementName'); @@ -233,9 +239,17 @@ function showAchievementInfo(achievement) { image.src = achievement.image; name.textContent = achievement.name; - description.textContent = achievement.description; - unlockedClasses.innerHTML = '
Classes:
'; + if (achievement.unlocked) { + name.classList.remove('locked'); + description.textContent = achievement.description; + } else { + name.classList.add('locked'); + description.textContent = `Unlock Requirements: ${achievement.unlock_requirements}`; + } + + // Display unlockable items for both locked and unlocked achievements + unlockedClasses.innerHTML = '
Classes Unlocked:
'; if (achievement.unlocked_classes && achievement.unlocked_classes.length > 0) { achievement.unlocked_classes.forEach(c => { unlockedClasses.innerHTML += `
${c.name}${c.name}
`; @@ -244,7 +258,7 @@ function showAchievementInfo(achievement) { unlockedClasses.innerHTML += '

No classes unlocked

'; } - unlockedSkins.innerHTML = '
Skins:
'; + unlockedSkins.innerHTML = '
Skins Unlocked:
'; if (achievement.unlocked_skins && achievement.unlocked_skins.length > 0) { achievement.unlocked_skins.forEach(s => { unlockedSkins.innerHTML += `
${s.name}${s.name}
`; @@ -253,8 +267,8 @@ function showAchievementInfo(achievement) { unlockedSkins.innerHTML += '

No skins unlocked

'; } - // For debugging - debugLog('Achievement:', achievement); + unlockedClasses.style.display = 'block'; + unlockedSkins.style.display = 'block'; } function hideAchievementInfo() { diff --git a/static/styles.css b/static/styles.css index 01e74ae..eaf61cd 100644 --- a/static/styles.css +++ b/static/styles.css @@ -1306,6 +1306,31 @@ body { flex: 1; } +.achievement.locked { + border-color: #ff00ff; +} + +.achievement.locked img { + filter: grayscale(100%) brightness(40%); +} + + +.achievement.locked::after { + content: '\f023'; /* Lock icon */ + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 24px; + color: #ff00ff; + text-shadow: 0 0 5px #ff00ff; +} + + + + #achievementsContainer { height: 100%; overflow-y: auto; @@ -1326,6 +1351,7 @@ body { overflow: hidden; cursor: pointer; transition: transform 0.2s; + position: relative; } .achievement:hover { @@ -1336,6 +1362,7 @@ body { width: 100%; height: 100%; object-fit: cover; + transition: filter 0.2s; } @@ -1643,14 +1670,12 @@ img { .achievements-grid { max-height: 40vh; - overflow-y: auto; } .achievement-info-box { width: 100%; border-left: none; border-top: 2px solid #00ffff; - padding: 10px; } .achievement-info-box img {