Div Erweiterungen

This commit is contained in:
2025-09-15 23:52:59 +02:00
parent ad6ba66220
commit 5ca7b0b19c
9 changed files with 2567 additions and 24 deletions

View File

@@ -58,6 +58,9 @@ class AchievementSystem {
*/
async loadPlayerAchievements(playerId) {
try {
// Initialisiere immer eine leere Map für den Spieler
this.playerAchievements.set(playerId, new Map());
const result = await pool.query(`
SELECT pa.achievement_id, pa.progress, pa.is_completed, pa.earned_at
FROM player_achievements pa
@@ -66,7 +69,6 @@ class AchievementSystem {
`, [playerId]);
// Gruppiere nach achievement_id und zähle Completions
this.playerAchievements.set(playerId, new Map());
const achievementCounts = new Map();
result.rows.forEach(pa => {
@@ -87,6 +89,7 @@ class AchievementSystem {
});
});
console.log(`📋 ${result.rows.length} Achievements für Spieler ${playerId} geladen`);
return true;
} catch (error) {
console.error(`❌ Fehler beim Laden der Spieler-Achievements für ${playerId}:`, error);
@@ -122,6 +125,12 @@ class AchievementSystem {
async checkImmediateAchievements(playerId) {
console.log(`⚡ Prüfe sofortige Achievements für Spieler ${playerId}...`);
// Lade alle Achievements (falls noch nicht geladen)
if (this.achievements.size === 0) {
console.log('📋 Lade alle Achievements...');
await this.loadAchievements();
}
// Lade Spieler-Achievements
await this.loadPlayerAchievements(playerId);
@@ -216,6 +225,17 @@ class AchievementSystem {
for (const achievement of achievements) {
if (this.isAchievementCompleted(playerId, achievement.id)) continue;
// Prüfe ob das Achievement heute bereits vergeben wurde
const alreadyEarnedToday = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
`, [playerId, achievement.id]);
if (parseInt(alreadyEarnedToday.rows[0].count) > 0) continue;
if (attemptsToday >= achievement.condition_value) {
await this.awardAchievement(playerId, achievement, attemptsToday, newAchievements);
}
@@ -322,6 +342,17 @@ class AchievementSystem {
for (const achievement of achievements) {
if (this.isAchievementCompleted(playerId, achievement.id)) continue;
// Prüfe ob das Achievement heute bereits vergeben wurde
const alreadyEarnedToday = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
`, [playerId, achievement.id]);
if (parseInt(alreadyEarnedToday.rows[0].count) > 0) continue;
// Prüfe ob Spieler zu dieser Zeit gespielt hat
const hasPlayed = await this.checkTimeBasedPlay(playerId, timeAchievement.condition);
@@ -510,7 +541,18 @@ class AchievementSystem {
const achievement = Array.from(this.achievements.values())
.find(a => a.category === 'best_time' && a.condition_type === 'daily_best');
if (!achievement || this.isAchievementCompleted(playerId, achievement.id)) return;
if (!achievement) return;
// Prüfe ob das Achievement heute bereits vergeben wurde
const alreadyEarnedToday = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') = CURRENT_DATE
`, [playerId, achievement.id]);
if (parseInt(alreadyEarnedToday.rows[0].count) > 0) return;
// Hole beste Zeit des Spielers heute
const playerResult = await pool.query(`
@@ -542,14 +584,25 @@ class AchievementSystem {
const achievement = Array.from(this.achievements.values())
.find(a => a.category === 'best_time' && a.condition_type === 'weekly_best');
if (!achievement || this.isAchievementCompleted(playerId, achievement.id)) return;
if (!achievement) return;
// Berechne Wochenstart (Montag)
// Prüfe ob das Achievement diese Woche bereits vergeben wurde
const currentDateObj = new Date(currentDate);
const dayOfWeek = currentDateObj.getDay();
const weekStart = new Date(currentDateObj);
weekStart.setDate(currentDateObj.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1));
const weekStartStr = weekStart.toISOString().split('T')[0];
const alreadyEarnedThisWeek = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') >= $3
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') <= $4
`, [playerId, achievement.id, weekStartStr, currentDate]);
if (parseInt(alreadyEarnedThisWeek.rows[0].count) > 0) return;
// Hole beste Zeit des Spielers diese Woche
const playerResult = await pool.query(`
@@ -583,12 +636,24 @@ class AchievementSystem {
const achievement = Array.from(this.achievements.values())
.find(a => a.category === 'best_time' && a.condition_type === 'monthly_best');
if (!achievement || this.isAchievementCompleted(playerId, achievement.id)) return;
if (!achievement) return;
// Berechne Monatsstart
const currentDateObj = new Date(currentDate);
const monthStart = new Date(currentDateObj.getFullYear(), currentDateObj.getMonth(), 1);
const monthStartStr = monthStart.toISOString().split('T')[0];
// Prüfe ob das Achievement diesen Monat bereits vergeben wurde
const alreadyEarnedThisMonth = await pool.query(`
SELECT COUNT(*) as count
FROM player_achievements pa
WHERE pa.player_id = $1
AND pa.achievement_id = $2
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') >= $3
AND DATE(pa.earned_at AT TIME ZONE 'Europe/Berlin') <= $4
`, [playerId, achievement.id, monthStartStr, currentDate]);
if (parseInt(alreadyEarnedThisMonth.rows[0].count) > 0) return;
// Hole beste Zeit des Spielers diesen Monat
const playerResult = await pool.query(`
@@ -656,7 +721,10 @@ class AchievementSystem {
// Für einmalige Achievements prüfen wir, ob sie bereits erreicht wurden
const playerAchievements = this.playerAchievements.get(playerId);
if (!playerAchievements) return false;
if (!playerAchievements) {
console.log(`⚠️ Player achievements not loaded for ${playerId}, assuming not completed`);
return false;
}
return playerAchievements.has(achievementId);
}