Achivements überarbeitet

This commit is contained in:
2025-09-15 20:23:20 +02:00
parent 7cce818932
commit ad6ba66220
6 changed files with 410 additions and 18 deletions

View File

@@ -33,7 +33,7 @@ class AchievementSystem {
async loadAchievements() {
try {
const result = await pool.query(`
SELECT id, name, description, category, condition_type, condition_value, icon, points
SELECT id, name, description, category, condition_type, condition_value, icon, points, can_be_earned_multiple_times
FROM achievements
WHERE is_active = true
ORDER BY category, condition_type
@@ -384,7 +384,7 @@ class AchievementSystem {
}
/**
* Prüft monatliche Achievements
* Prüft monatliche Achievements (einmal pro Jahr)
*/
async checkMonthlyAchievements(playerId, currentMonth, newAchievements) {
const monthNames = [
@@ -393,6 +393,7 @@ class AchievementSystem {
];
const currentMonthName = monthNames[currentMonth - 1];
const currentYear = new Date().getFullYear();
const achievements = Array.from(this.achievements.values())
.filter(a => a.category === 'monthly' && a.condition_type === currentMonthName);
@@ -400,26 +401,39 @@ class AchievementSystem {
for (const achievement of achievements) {
if (this.isAchievementCompleted(playerId, achievement.id)) continue;
// Prüfe ob Spieler in diesem Monat gespielt hat
// Prüfe ob Spieler in diesem Monat dieses Jahres gespielt hat
const result = await pool.query(`
SELECT EXISTS(
SELECT 1 FROM times t
WHERE t.player_id = $1
AND EXTRACT(MONTH FROM t.created_at AT TIME ZONE 'Europe/Berlin') = $2
AND EXTRACT(YEAR FROM t.created_at AT TIME ZONE 'Europe/Berlin') = $3
) as has_played
`, [playerId, currentMonth]);
`, [playerId, currentMonth, currentYear]);
if (result.rows[0].has_played) {
await this.awardAchievement(playerId, achievement, 1, newAchievements);
// Prüfe ob Achievement bereits in diesem Jahr erreicht wurde
const alreadyEarnedThisYear = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND EXTRACT(YEAR FROM pa.earned_at AT TIME ZONE 'Europe/Berlin') = $3
`, [playerId, achievement.id, currentYear]);
if (parseInt(alreadyEarnedThisYear.rows[0].count) === 0) {
await this.awardAchievement(playerId, achievement, 1, newAchievements);
}
}
}
}
/**
* Prüft Jahreszeiten-Achievements
* Prüft Jahreszeiten-Achievements (einmal pro Jahr)
*/
async checkSeasonalTimeAchievements(playerId, currentMonth, newAchievements) {
const season = this.getSeason(currentMonth);
const currentYear = new Date().getFullYear();
const achievements = Array.from(this.achievements.values())
.filter(a => a.category === 'seasonal' && a.condition_type === season);
@@ -427,7 +441,7 @@ class AchievementSystem {
for (const achievement of achievements) {
if (this.isAchievementCompleted(playerId, achievement.id)) continue;
// Prüfe ob Spieler in dieser Jahreszeit gespielt hat
// Prüfe ob Spieler in dieser Jahreszeit dieses Jahres gespielt hat
const monthRanges = {
spring: [3, 4, 5],
summer: [6, 7, 8],
@@ -441,11 +455,23 @@ class AchievementSystem {
SELECT 1 FROM times t
WHERE t.player_id = $1
AND EXTRACT(MONTH FROM t.created_at AT TIME ZONE 'Europe/Berlin') = ANY($2)
AND EXTRACT(YEAR FROM t.created_at AT TIME ZONE 'Europe/Berlin') = $3
) as has_played
`, [playerId, months]);
`, [playerId, months, currentYear]);
if (result.rows[0].has_played) {
await this.awardAchievement(playerId, achievement, 1, newAchievements);
// Prüfe ob Achievement bereits in diesem Jahr erreicht wurde
const alreadyEarnedThisYear = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND EXTRACT(YEAR FROM pa.earned_at AT TIME ZONE 'Europe/Berlin') = $3
`, [playerId, achievement.id, currentYear]);
if (parseInt(alreadyEarnedThisYear.rows[0].count) === 0) {
await this.awardAchievement(playerId, achievement, 1, newAchievements);
}
}
}
}
@@ -617,12 +643,22 @@ class AchievementSystem {
/**
* Prüft ob ein Achievement bereits erreicht wurde
* Jetzt können Achievements mehrmals erreicht werden, daher immer false
* Berücksichtigt ob das Achievement mehrmals erreicht werden kann
*/
isAchievementCompleted(playerId, achievementId) {
// Achievements können jetzt mehrmals erreicht werden
// Daher prüfen wir nicht mehr, ob sie bereits erreicht wurden
return false;
const achievement = this.achievements.get(achievementId);
if (!achievement) return false;
// Wenn das Achievement mehrmals erreicht werden kann, ist es nie "abgeschlossen"
if (achievement.can_be_earned_multiple_times) {
return false;
}
// Für einmalige Achievements prüfen wir, ob sie bereits erreicht wurden
const playerAchievements = this.playerAchievements.get(playerId);
if (!playerAchievements) return false;
return playerAchievements.has(achievementId);
}
/**