fix: quests respect zone locking + level ordering fixes
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 35s

Quêtes d'arcs filtrées par zones débloquées — pas de quête Égouts
visible tant que l'arc Marais n'est pas complété.
Gardien des marais: level 5→4. Dératisation: level 4→5.
Exterminateur: description corrigée (kill_any x30, pas "chaque espèce").
This commit is contained in:
2026-03-24 18:27:36 +01:00
parent b414200544
commit 810ad5ee64

View File

@@ -8,6 +8,7 @@ import { QuestArc } from './quest-arc.entity';
import { PlayerQuest } from './player-quest.entity'; import { PlayerQuest } from './player-quest.entity';
import { PlayerQuestArc } from './player-quest-arc.entity'; import { PlayerQuestArc } from './player-quest-arc.entity';
import { Character } from '../character/entities/character.entity'; import { Character } from '../character/entities/character.entity';
import { getUnlockedZones } from '../common/zone-access';
const MAX_ACTIVE_QUESTS = 3; const MAX_ACTIVE_QUESTS = 3;
@@ -39,6 +40,9 @@ export class QuestService {
}); });
const questStatusMap = new Map(playerQuests.map((pq) => [pq.questId, pq.status])); const questStatusMap = new Map(playerQuests.map((pq) => [pq.questId, pq.status]));
// Zone locking — only show quests from unlocked zones
const unlockedZones = await getUnlockedZones(characterId, this.arcRepo, this.playerArcRepo);
const quests = await this.questRepo.find({ const quests = await this.questRepo.find({
relations: ['arc'], relations: ['arc'],
order: { arcOrder: 'ASC' }, order: { arcOrder: 'ASC' },
@@ -47,10 +51,11 @@ export class QuestService {
return quests.filter((q) => { return quests.filter((q) => {
if (q.minLevel > character.level) return false; if (q.minLevel > character.level) return false;
// Zone filter: if quest belongs to an arc with a zone, check zone is unlocked
if (q.arc?.zone && !unlockedZones.includes(q.arc.zone)) return false;
const status = questStatusMap.get(q.id); const status = questStatusMap.get(q.id);
// Already active or completed (waiting claim) → not available
if (status === 'active' || status === 'completed') return false; if (status === 'active' || status === 'completed') return false;
// Already claimed and not repeatable → not available
if (status === 'claimed' && !q.repeatable) return false; if (status === 'claimed' && !q.repeatable) return false;
return true; return true;